I'm trying to make some static controls transparent on a windows dialog, but I'm having difficulty with one windows message.
Windows happily sends me a WM_CTLCOLORSTATIC message when drawing static controls, but this message is also sent to readonly and disabled edit controls. So - given just a hwnd to the control, how can I tell what kind of control it is?
You could call GetClassName i.e
// given controlHwnd passed to me
TCHAR controlClassName[128];
GetClassName(controlHwnd,controlClassName,128);
You'd then have to do a bunch of string compares based on the string i.e "Button" - so not great but should work.
In case you don't have many controls, use GetDlgCtrlID() to get control's resource id.
With that info, you can filter out any controls that you don't want.
Use the GetClassName function. Some of the predefined class names like BUTTON are listed here. See also How To Get a Window's Class Name and Other Window Attributes.
It's the 'class name' that determines what "kind" of control it is (more specifically, the class defines the window procedure, which defines the control's behaviour ... or only slightly more complicated if the control has been subclassed by someone).
As an optimization, you could first try to find your first Static control by using GetClassName and string compares, then, once you find one, store its class atom gotten using GetClassLong(hWnd, GCW_ATOM) and compare atoms from now on.
Related
I am extending a few controls on MFC to be used in multiple applications. I have a derived class to extend labels and groupboxes alike, since they are both static labels and only required draw operation.
In my derived class Label : public CWnd, I have properly written the OnEraseBkgnd and OnPaint msg handlers. Everything works well with Labels and groupboxed, I don't mind drawing everything myself.
My question is, from this derived class' perspective, how do I determine if I am a static label or a group box?
I could of course add a member variable or function to indicate control type, set it somewhere in the beginning of the application, and check it and draw accordingly. But I would like to solve this in the extended class's code, not on application code.
Note: I have tried GetStyle() and checking BS_GROUPBOX, it does not help, since some combination of static styles SS_* can be same as BS_GROUPBOX.
The style attributes from GetStyle() are different for each control class. After determining that it is a static, looking at the its style will help decide what type of static it is.
Since a group box is a button, you will need to check for a BUTTON class class with a style of BS_GROUPBOX.
One thing to keep in mind, a button's style uses the lower 4 bits to determine type. Use BS_TYPEMASK to get just the button style.
if ( (GetStyle() & BS_TYPEMASK) == BS_GROUPBOX ) {
// etc
}
There are two methods to get window icon if i know his handle:
SendMessage(HWND,0x7F lParam, wParam)
and
GetClassLong(HWND, -14|-34)
But even if I get icon from window with GetClassLong i can't set new icon with SetClassLong, but successfully set new icon with SendMessage.
I need to know: why in some times work second get method, but doen't work first method. And why always from SendMessage(WN_SETICON) and doen't work SetClassLong(HWND, -14|-34, HICON)?
GetClassLong retrieves longs from the window class.
A window class is a blueprint for creating a window of a specified type, not the window itself.
It can contain quite a lot of defaults, like the default icon, and the default small icon.
But a window is only based on it, it can override everything.
Thus, setting the windowclass' icon does not modify any already created classes, you must send a message to the window instead.
And reading the windowclass-data gets you stale data, which might or might not still be relevant to the window.
As an aside, -14|-34 would be GCL_HICON|GCL_HICONSM, or -2, which does not actually make sense.
Explicitly say that you read with both indices one after the other.
-14 is GCL_HICON which is the (optional resource) icon for the class specified when its registered.
A specific window can subsequently specify its own icon (WM_SETICON), subsequent changes to
GCL_HICON won't affect it.
I also doubt you can attempt to pull GCL_HICON | GCL_HICONSM, if they were different what would the value be?
A few additional things:
1) Don't use magic numbers for Windows API constant values. Use WM_GETICON, not 0x7F. Use the GCL_ names as mentioned by the other answers.
2) You switched wParam and lParam in your SendMessage(). wParam comes first.
3) Don't use GetClassLong(); it is not 64-bit safe (and icon handles are pointers). Use GetClassLongPtr() instead. Also substitute GCLP_ for GCL_ in your named constants.
4) Don't try to replace | in your GetClassLong() with || or with an array of indices and expect that to work either. You don't have a choice but to make two calls.
I have a subclass of CComboBox that behaves differently in two different
contexts - both in native C++. In the working (test) context the top-level application was created
using VS2008. In the non-working case the application is greatly more complex
and was probably originally created by an earlier VS version.
In the failure case the control won't display a dropdown box, but responds to
up/down arrow key controls. Also in the failure case it always returns zero
when queried using GetMinVisible and always returns failure from
SetMinVisibleItems.
It appears that the problem is rooted in the definition of the COMBOBOX window
class. I have dumped the data returned from ::GetClassInfoEx in both cases.
Aside from the address of the wndProc, there are two differences. First, the working
case has style CS_GLOBALCLASS set while the failure case doesn't. Also the
working case specifies 4 bytes of extra window storage (cbWndExtra) while the
failure case specifies 8 bytes.
So my questions are: 1) What configuration properties might affect the definition of
the COMBOBOX window class?, and 2) How can I determine the correct wndProc to use if I make my own window class?
EDIT: The behavior of the dropdown box changes with the specification of the character set property in the General property tab. It works as expected if character set is unicode and fails when it's not set. The combo box subclass is in an ActiveX control, but the setting at the application level seems to affect the window class, which winds up messing up the combo box in ActiveX control. Interestingly there are other combo boxes, albeit in dialogs, elsewhere in the application that seem to behave just fine.
SetMinVisibleItems uses CB_SETMINVISIBLE and it requires comctl32 v6, this is your clue that this is a visual styles issue.
The older common controls version of the combobox actually uses the controls height as the size of the drop-down list so if you adjust that you might be able to fix it without adding a manifest.
I have created a simple game using Win32 and gdi. I would like to have a track bar at the bottom that tracks a global variable. I'm just not sure how to add controls. How could I add a trackbar? I can imagine it would get created in the wm_create event.
Do you mean TrackBar or StatusBar?
A StatusBar is normally located at the bottom of a window and displays informational messages about the application status, a TrackBar allows the user to select a value. Do you want to allow the user to select the value of your global variable or do you just want to display the current value of the variable? (I'm not sure if the trackbar will display the current value of the variable without extra work.)
Either way, there are samples for both StatusBar and TrackBar located on MSDN.
The child windows are normally created either in the WM_CREATE of the parent or after the parent window has been created (i.e. when you obtain a valid hWnd for the parent) and after calling InitCommonControls() and/or initializing COM if needed.
To create controls on the fly, in general use the CreateWindow function. With a bit of googling for "TrackBar+CreateWindow" you'll find a number of samples for your question:
i.e.:
http://zetcode.com/gui/winapi/controlsII/
or
http://msdn.microsoft.com/en-us/library/bb760151%28VS.85%29.aspx
In my (PowerBuilder) application, I'd like to be able to determine the graphicobject object which corresponds to a given window handle.
Simply iterating over the Control[] array and comparing the value returned by the Handle() function for each of the child controls doesn't work, since not all objects in my application are children of the main window (consider of login dialogs).
Any PowerScript or C/C++ solution would be acceptable.
Is there maybe some window message I could send to window handles, and this message is only understood by PowerBuilder windows, which would the respond with their internal object name, or the like?
Is it a requirement to determine the object from the handle, or do you just want to identify an object, for example to know where the code you need to modify is? I made a tool that does the latter, but it uses object focus, rather than window handles.
(added 2010-06-21) For windows that aren't children of the main window you could explicitly check each of these window class names with isValid(). Then for each valid window, dig through looking for the handle. This should work as long as you only open one instance of the window class at a time. If you open multiple instances, I think you'll need to add a registration mechanism to the open of those windows so the application has a way to access them.