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
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
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.
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.
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.
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:
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.
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!
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?
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!
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
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.
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.
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!
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.
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?
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.