Hi, mates,
I'm trying to create a ComboBox with its associated ListBox which can have some disabled items (h..p://www.codeproject.com/combobox/disableditemscombobox.asp is an initial tutorial for this, even if it uses MFC).
If I define the ComboBox with the style CBS_OWNERDRAWFIXED inside the .RC file, everything works ok: I see WM_DRAWITEM messages from the ListBox inside my subclassed ComboBox window procedure.
On the other hand, if I try to set that style "on the fly", after the ComboBox creation, using SetWindowLong(GWL_STYLE), it does not work :(
Can you confirm this?
Is there some way to set that style after the control creation, without interferences with the Resource Section of the executable?
Thanks, bilbo
I'm trying to create a ComboBox with its associated ListBox which can have some disabled items (h..p://www.codeproject.com/combobox/disableditemscombobox.asp is an initial tutorial for this, even if it uses MFC).
If I define the ComboBox with the style CBS_OWNERDRAWFIXED inside the .RC file, everything works ok: I see WM_DRAWITEM messages from the ListBox inside my subclassed ComboBox window procedure.
On the other hand, if I try to set that style "on the fly", after the ComboBox creation, using SetWindowLong(GWL_STYLE), it does not work :(
Can you confirm this?
Is there some way to set that style after the control creation, without interferences with the Resource Section of the executable?
Thanks, bilbo
Some styles can't be changed after control creation, and some you can but not through SetWindowLong but specific APIs (like WS_EX_TOPMOST). I don't know about this particular case but it wouldn't be surprising.
If for some reason you can't set this style directly on window creation, you can destroy the control and create a new one in it's place. If the problem is that you want it to be user configurable, you can load the dialog box template "by hand" from the resources (or simply put it in your .data section), and change it on runtime. Then you can load the dialog indirectly.
Hope that helps :)
If for some reason you can't set this style directly on window creation, you can destroy the control and create a new one in it's place. If the problem is that you want it to be user configurable, you can load the dialog box template "by hand" from the resources (or simply put it in your .data section), and change it on runtime. Then you can load the dialog indirectly.
Hope that helps :)
Thanks for your answer, QvasiModo!
I'm yet trying to understand for what obscure reason it is not possible to change some styles after control creation.
Then I'll try your suggested trick: destroying the control and recreating it using the same dialog box template, modified by hand.
Thanks again
bilbo
I'm yet trying to understand for what obscure reason it is not possible to change some styles after control creation.
Then I'll try your suggested trick: destroying the control and recreating it using the same dialog box template, modified by hand.
Thanks again
bilbo
Hi, mates,
I'm yet investigating why in the hell the SetWindowLong() does not work for all styles...
In the meantime I completed the implementation of QvasiModo trick. I've found two unexpected problems:
(1) you cannot patch "by hand" inside the resource section because it is write protected. We can copy it in our .data section (as QvasiModo suggested) but we need to know its length, OR we simply call VirtualProtect(PAGE_READWRITE) before the patch
(2) some caution must be taken to avoid interferences between the old and the new window, since the window procedure is the same. After DestroyWindow(old window) we must intercept all following messages directed to the old window, else the whole application will quit (this is due to the fact that usually WM_DESTROY is handled by PostQuitMessage())
Regards, bilbo
I'm yet investigating why in the hell the SetWindowLong() does not work for all styles...
In the meantime I completed the implementation of QvasiModo trick. I've found two unexpected problems:
(1) you cannot patch "by hand" inside the resource section because it is write protected. We can copy it in our .data section (as QvasiModo suggested) but we need to know its length, OR we simply call VirtualProtect(PAGE_READWRITE) before the patch
(2) some caution must be taken to avoid interferences between the old and the new window, since the window procedure is the same. After DestroyWindow(old window) we must intercept all following messages directed to the old window, else the whole application will quit (this is due to the fact that usually WM_DESTROY is handled by PostQuitMessage())
Regards, bilbo
1) Sounds reasonable. Maybe you could infer the size of the dialog box from it's structure, I'm sure it was documented somewhere in win32.hlp so it must be in MSDN as well. :)
2) Weird! :? A control's window procedure should never call PostQuitMessage, under any circumstance. Maybe I didn't understand the problem?
2) Weird! :? A control's window procedure should never call PostQuitMessage, under any circumstance. Maybe I didn't understand the problem?
A control's window procedure should never call PostQuitMessage, under any circumstance. Maybe I didn't understand the problem?
Well, to simplify my code I deleted the whole dialog, containing the control, not just that single control. Next I recreated the dialog using the patched resource and CreateDialogIndirect(). Now, the application I'm playing with (h..p://members.a1.net/ranmasaotome/masm32/Combobox.zip) uses just a dialog box as main window, and WM_DESTROY is handled by a standard PostQuitMessage call.
Thanks, bilbo