CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Oct 2013
    Posts
    39

    List View Report questions and bugs (?)

    okay, so I'm creating a listview with report style, however I'm having some troubles with it, I'm creating it in .rc not via function, like this

    Code:
    CONTROL         "", IDC_LIST, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT, 5, 10, 180, 150
    now for the problems;

    1. it is possible to select an item, however only by selecting the first column, not any other (I also need to click on the first ~half of the column, otherwise it wont select)
    2. when I select an item, it will allign it to the left, while normally it is alligned to the center and it will stay alligned to the left even after unselect, unless I select another item

    here's the screenshot, I need to click to the highlighted area in order to select an item, the item will get selected (only item, not full row - row wont get selected even with LVS_EX_FULLROWSELECT) and alligned to the left

    Name:  2e7521c7899d6c9890cd0bde9f6ae804.jpg
Views: 503
Size:  21.9 KB

    now what I want to do is a possibility to select a full row (item and it's subitems) WITHOUT breaking my code (when I use LVS_EX_FULLROWSELECT it wont load data properly and will mess them up) and alligning the stuff to the left

    p.s.: please ignore the comments as this is school project and I have to comment everything

    project:

    CSV.zip

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Code:
                HWND hTmp = GetDlgItem(hWnd, IDC_LIST);
                
                ListView_SetExtendedListViewStyle(hTmp, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    And please never rape strings like you did.
    Code:
    int InsertToList(HWND hWnd, vector<string> str)
    {
        int len = str.size();
        if(len < 1)
            return 0;
    
        LVITEM lvi;
        lvi.mask = LVIF_TEXT;
        lvi.iItem = ListView_GetItemCount(hWnd);
        lvi.iSubItem = 0;
        lvi.pszText = (LPSTR)str[0].c_str();
    
        ListView_InsertItem(hWnd, &lvi);
    
        if(len > COLUMN_MAX)
            len = COLUMN_MAX;
    
        for(int i = 1; i < len; i++)
        {
            lvi.pszText = (LPSTR)str[i].c_str();
            lvi.iSubItem++;
            ListView_SetItem(hWnd, &lvi);
        }
    
        return 1;
    }
    As for the WinMain structure, I really don't get why would anybody go this way. Dialog requiring class registration... last time I met something like that was back in Win16 ages. When I use dialogs, I use standard dialog approaches.

    Code:
    INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, INT nShowCmd)
    {
    	INITCOMMONCONTROLSEX icex;
    	icex.dwICC = ICC_LISTVIEW_CLASSES;
    	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    	InitCommonControlsEx(&icex);
    
    	BOOL res = DialogBox(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc);
    	return 0;
    
    }
    Last edited by Igor Vartanov; February 13th, 2014 at 04:20 AM.
    Best regards,
    Igor

  3. #3
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Made it my way. FYI, I tackled WinMain and MainDlgProc only, as I never wanted to go any deeper.
    Attached Files Attached Files
    Last edited by Igor Vartanov; February 13th, 2014 at 05:09 AM.
    Best regards,
    Igor

  4. #4
    Join Date
    Oct 2013
    Posts
    39

    Re: List View Report questions and bugs (?)

    wow, thanks, it was driving me crazy last few days and I had no idea the "ex" stands for extended and I have to add it this way (I thought it's ex, as "old", you know how I mean it...), anyway, why is using class for dialog window (when it's as main window) bad thing? it's good for everything I need, for example when I want to use icon, small icon, change cursor, add menu etc... and it works just fine, also what was wrong on how I used the vector of strings? as far as I remember, I was told that vector content is returned like this
    Code:
    &vctr[i]
    but it did need a char pointer...

    also as I can see, you are using return TRUE instead of break in INITDIALOG, why? isnt it the same?
    Last edited by DaigonoYouso; February 13th, 2014 at 11:20 AM.

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Quote Originally Posted by DaigonoYouso View Post
    anyway, why is using class for dialog window (when it's as main window) bad thing? it's good for everything I need, for example when I want to use icon, small icon, change cursor, add menu etc... and it works just fine,
    It's not a bad thing... It's kinda weird thing. There are normal windows requiring class registration to specify window procedure, icons, brushes and the stuff. And there are dialogs, the special window class already registered in Windows with class name "#32770", colors and the stuff and requiring dialog procedure be specified at the moment of creation. So, dialog with window class is something... weird.

    Nothing prevents from assigning an icon to classic dialog window, or cursor, or colors, so my understanding is: dialogs should remain dialogs. But you surely may think different.

    also what was wrong on how I used the vector of strings? as far as I remember, I was told that vector content is returned like this
    Code:
    &vctr[i]
    but it did need a char pointer...
    Operator [] provides the access to vector's element, so vcrt[i] is a std::string. And the way to get string content is .c_str() method but not operator &().

    also as I can see, you are using return TRUE instead of break in INITDIALOG, why? isnt it the same?
    Read about WM_INIDIALOG to answer your question. And please note, WM_INITDIALOG is a specific message, for real dialogs only.
    Last edited by Igor Vartanov; February 14th, 2014 at 10:59 PM.
    Best regards,
    Igor

  6. #6
    Join Date
    Oct 2013
    Posts
    39

    Re: List View Report questions and bugs (?)

    Quote Originally Posted by Igor Vartanov View Post
    It's not a bad thing... It's kinda weird thing. There are normal windows requiring class registration to specify window procedure, icons, brushes and the stuff. And there are dialogs, the special window class already registered in Windows with class name "#32770", colors and the stuff and requiring dialog procedure be specified at the moment of creation. So, dialog with window class is something... weird.

    Nothing prevents from assigning an icon to classic dialog window, or cursor, or colors, so my understanding is: dialogs should remain dialogs. But you surely may think different.

    Operator [] provides the access to vector's element, so vcrt[i] is a std::string. And the way to get string content is .c_str() method but not operator &().


    Read about WM_INIDIALOG to answer your question. And please note, WM_INITDIALOG is a specific message, for real dialogs only.
    but, is there ANYTHING wrong with it, or is it just that it's not needed and it's there in addition? so uhm, since im using wndclass, my dialog is not real dialog ? I just learned win32api basic stuff from some tutorials, so this is kinda confusing

    anyway, is there a solution for when I subclass edit control, when I press escape, while I have focus on edit control, it will close the whole dialog... whole subclass proc:

    Code:
    BOOL CALLBACK ItemEditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
    {
    	switch(msg)
    	{
    	case WM_CHAR:
    		{
    			switch(wParam)
    			{
    			case VK_RETURN:
    				{
    					char tmp[32];
    					SendMessage(hWnd, WM_GETTEXT, 32, (LPARAM)tmp);
    					ListView_SetItemText(Selected.hWnd, Selected.item, Selected.subitem, tmp);
    					SetFocus(Selected.hWnd);
    					Selected.Reset();
    
    					return 0;
    				}
    			case VK_ESCAPE:
    				{
    					SetFocus(Selected.hWnd);
    					Selected.Reset();
    
    					return 0;
    				}
    			}
    			break;
    		}
    	default:
    		return DefSubclassProc(hWnd, msg, wParam, lParam);
    	}
    	return DefSubclassProc(hWnd, msg, wParam, lParam);
    }
    why is it doing that and how to prevent it?

    edit: yes, the edit control is multiline, when not using multiline it wont accept return, even with ES_WANTRETURN style, suggestions? also how can I force the edit control to take more chars that it's size? I tried EM_SETLIMITTEXT, but it didnt work, I guess that's only for single line edit controls
    Last edited by DaigonoYouso; February 17th, 2014 at 09:26 AM.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List View Report questions and bugs (?)

    anyway, is there a solution for when I subclass edit control, when I press enter it will do the "beep" sound, also when I press escape, while I have focus on edit control, it will close the whole dialog... whole subclass proc:
    After you have processed the msg's in your subclass function you are still calling the original def proc which does what it is designed to - beep, close etc. After you have processed a key such as VK_RETURN or VK_ESCAPE, just return rather than calling DefSubclassProc().

    This is more complicated example of a subclass proc for an edit control but it should give you the general idea.

    Code:
    //New wnd proc for edit control in value control
    LRESULT CALLBACK NewEdit(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    {
    HWND	hanc = GetAncestor(hwnd, GA_ROOT);
    
    PLSGM	lsgm = (PLSGM)GetWindowLong(hanc, WEX_LS);
    
    UINT	id = GetWindowLong(GetParent(hwnd), GWL_ID) - STID;
    
    	//Check for special char tab, CR, shift tab use WM_KEYDOWN so can check for VK_SHIFT
    	if (message == WM_KEYDOWN) {
    
    		//If tab or CR then process as tab/CR from main control and move to other control
    		if ((wparam == VK_TAB) || (wparam == VK_RETURN)) {
    			if (wparam == VK_TAB) {
    				if ((USHORT)GetKeyState(VK_SHIFT) > 1) {
    					wparam = VK_BACK;
    				}
    			}
    
    			//Set lv text and close edit control
    			SetLVtext(lsgm);
    
    			//Process tab/CR
    			//CR now just closes and updates edit control
    			if (wparam != VK_RETURN) {
    				doTabCR(hanc, id + 1, wparam);
    			}
    			return (0);
    		}
    	}
    
    
    	if (message == WM_CHAR) {
    
    		//Ignore tab/CR as processed using WM_KEYDOWN
    		if ((wparam == TAB) || (wparam == CR)) {
    			return (0);
    		} else {
    
    			//If have ESC then close edit window but don't save contents
    			if (wparam == ESC) {
    
    				//Indicate edit control contents not changed
    				lsgm->lvdef.chg = FALSE;
    				DestroyWindow(hwnd);
    				return (0);
    			} else {
    
    				//Indicate contents changed
    				lsgm->lvdef.chg = TRUE;
    			}
    		}
    	}
    
    	//If edit control loose focus, save contents and close edit window
    	if (message == WM_KILLFOCUS) {
    		SetLVtext(lsgm);
    		return (0);
    	}
    
    	//Process message as normal
    	return (CallWindowProc(lsgm->lvdef.old, hwnd, message, wparam, lparam));
    }
    Last edited by 2kaud; February 17th, 2014 at 09:37 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Join Date
    Oct 2013
    Posts
    39

    Re: List View Report questions and bugs (?)

    Quote Originally Posted by 2kaud View Post
    After you have processed the msg's in your subclass function you are still calling the original def proc which does what it is designed to - beep, close etc. After you have processed a key such as VK_RETURN or VK_ESCAPE, just return rather than calling DefSubclassProc().

    This is more complicated example of a subclass proc for an edit control but it should give you the general idea.

    Code:
    //New wnd proc for edit control in value control
    LRESULT CALLBACK NewEdit(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    {
    HWND	hanc = GetAncestor(hwnd, GA_ROOT);
    
    PLSGM	lsgm = (PLSGM)GetWindowLong(hanc, WEX_LS);
    
    UINT	id = GetWindowLong(GetParent(hwnd), GWL_ID) - STID;
    
    	//Check for special char tab, CR, shift tab use WM_KEYDOWN so can check for VK_SHIFT
    	if (message == WM_KEYDOWN) {
    
    		//If tab or CR then process as tab/CR from main control and move to other control
    		if ((wparam == VK_TAB) || (wparam == VK_RETURN)) {
    			if (wparam == VK_TAB) {
    				if ((USHORT)GetKeyState(VK_SHIFT) > 1) {
    					wparam = VK_BACK;
    				}
    			}
    
    			//Set lv text and close edit control
    			SetLVtext(lsgm);
    
    			//Process tab/CR
    			//CR now just closes and updates edit control
    			if (wparam != VK_RETURN) {
    				doTabCR(hanc, id + 1, wparam);
    			}
    			return (0);
    		}
    	}
    
    
    	if (message == WM_CHAR) {
    
    		//Ignore tab/CR as processed using WM_KEYDOWN
    		if ((wparam == TAB) || (wparam == CR)) {
    			return (0);
    		} else {
    
    			//If have ESC then close edit window but don't save contents
    			if (wparam == ESC) {
    
    				//Indicate edit control contents not changed
    				lsgm->lvdef.chg = FALSE;
    				DestroyWindow(hwnd);
    				return (0);
    			} else {
    
    				//Indicate contents changed
    				lsgm->lvdef.chg = TRUE;
    			}
    		}
    	}
    
    	//If edit control loose focus, save contents and close edit window
    	if (message == WM_KILLFOCUS) {
    		SetLVtext(lsgm);
    		return (0);
    	}
    
    	//Process message as normal
    	return (CallWindowProc(lsgm->lvdef.old, hwnd, message, wparam, lparam));
    }
    thanks, but I already edited the reply before you posted, anyway, it now doesnt beep, but still closes the main dialog, even when I return 0, also what's the difference between WM_CHAR and WM_KEYDOWN? also is returning 0/1 at the end, instead of defsubclassproc (call dsp only in default) a good idea?

    edit: also why do you use CallWindowProc and not a DefSubclassProc?

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List View Report questions and bugs (?)

    edit: also why do you use CallWindowProc and not a DefSubclassProc?
    When I subclass the control, I store the address of the original control proc in lsgm->lvdef.old which I then call via CallWindowProc().

    what's the difference between WM_CHAR and WM_KEYDOWN?
    See
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    WM_KEYDOWN message is posted before the WM_CHAR message.

    There is also a WM_KEYUP message as well
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    Last edited by 2kaud; February 17th, 2014 at 10:44 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Quote Originally Posted by DaigonoYouso View Post
    but, is there ANYTHING wrong with it, or is it just that it's not needed and it's there in addition? so uhm, since im using wndclass, my dialog is not real dialog ? I just learned win32api basic stuff from some tutorials, so this is kinda confusing
    CLASS statement

    MSDN says:
    Remarks

    The CLASS statement should only be used with special cases, because it overrides the normal processing of a dialog box. The CLASS statement converts a dialog box to a window of the specified class; depending on the class, this could give undesirable results. Do not use the redefined control-class names with this statement.
    Rephrasing the said above: don't do that unless you completely understand what you do.



    anyway, is there a solution for when I subclass edit control, when I press escape, while I have focus on edit control, it will close the whole dialog...
    It doesn't matter what you do in the subclassed control. Keyboard input is posted to message queue, and therefore gets processed by the message pump first of all. There it becomes translated to IDCANCEL command, which appears to be sent to your dialog directly, before you can do anything in the control. Naturally, a solution would be to prevent translating VK_ESCAPE while having input focus in the edit box.
    Best regards,
    Igor

  11. #11
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Well, another solution would be just ignoring IDCANCEL command but processing WM_SYSCOMMAND SC_CLOSE directly. Of course your Close button should have an ID different from IDCANCEL.
    Best regards,
    Igor

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List View Report questions and bugs (?)

    There it becomes translated to IDCANCEL command, which appears to be sent to your dialog directly, before you can do anything in the control. Naturally, a solution would be to prevent translating VK_ESCAPE while having input focus in the edit box.
    Doesn't keyboard input get translated into WM_KEYDOWN, WM_CHAR and WM_KEYUP messages (stating which key is being processed) which can be intercepted in the sub-class proc and processed/not processed as required and only passed to the original control proc if needed?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  13. #13
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: List View Report questions and bugs (?)

    Dialog Box Keyboard Interface

    The system automatically provides the keyboard interface for all modal dialog boxes. It does not provide the interface for modeless dialog boxes unless the application calls the IsDialogMessage function to filter messages in its main message loop. This means that the application must pass the message to IsDialogMessage immediately after retrieving the message from the message queue. The function processes the messages if it is for the dialog box and returns a nonzero value to indicate that the message has been processed and must not be passed to the TranslateMessage or DispatchMessage function.
    Messages get delivered to controls by calling DispatchMessage in the message pump. The default dialogbox keyboard processing happens before dispatching keyboard messages.
    Best regards,
    Igor

  14. #14
    Join Date
    Oct 2013
    Posts
    39

    Re: List View Report questions and bugs (?)

    thanks all, doing stuff with VK_ESCAPE works in WM_KEYDOWN, while VK_RETURN works in WM_CHAR, not sure why, if I try RETURN in KEYDOWN, it will still beep and if I try ESCAPE in char, it will close the dialog, anyway, does anybody have a solution for the other problem,

    how can I force the edit control to take more chars that it's size? I tried EM_SETLIMITTEXT, but it didnt work, I guess that's only for single line edit controls
    I dont really want the edit box to resize, is there any other option?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured