0

I got into some trouble I think caused by message sequencing in a dialog procedure. Trying to avoid more global variables, I added a WM_USER message to my dialog to set the color of a control. The message handling code simply stored the COLORREF in a static variable. In the INITDIALOG, I did a SendMessage(hDlg,WM_User...) (to the dialog itself) followed by a SetDlgItemText for an static control in the dialog. WM_CTLCOLORSTATIC message handling code sets the color, background color, and font for the static control. Everything seemed to work as expected until I overlaid the app with another from the task bar. When I re-established the app, the part of the static control that was hidden changed from the desired color to black. Note that the font size also changed by the WM_CTLCOLORSTATIC message was not affected. There is no way for this information to be regenerated so the windows dialog processing must save it somewhere. This, of course is impossible to debug because of interactions between the app and Visual Studio. When I replaced the SendMessage method of sending the color simply setting a global variable, the problem disappeared.

So, I'm curious about the messages that get sent to the dialog and the order in which they are sent? The MSDN says SendMessage does not return until the message has been processed by the window. So I guess the messages must look like this

WM_INITDIALOG starts

  WM_USER starts             (caused by the SendMessage call)
  WM_USER ends

  WM_CTLCOLORSTATIC starts   (caused by the SetDlgItemText call)
  WM_CTLCOLORSTATIC ends

WM_INITDIALOG ends

Meanwhile the static control is processing the WM_SETTEXT message before and after the WM_CTLCOLORSTATIC messages. I suppose other message such as WM_COMMAND/EN_CHANGE also get generated and processed.

If that's the case, I don't see what caused my problem or how it was fixed by eliminating the SendMessages.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Mike D
  • 2,753
  • 8
  • 44
  • 77
  • Is it possible that, rather than *explaining* your code, you could just actually *post* the code? So much easier to read that way. – Cody Gray - on strike Jul 25 '11 at 13:58
  • @David Hefferman: Mea culpa, I should have read the description of WM_USER more carefully; I guess it was one of those things I thought I knew about. – Mike D Jul 25 '11 at 18:20

1 Answers1

1

It turns out that something in windows was also sending WM_USER messages, changing to WM_APP fixed my problem. I am still curious as to the sequencing of messages in case anyone wants to respond to that

See WM_USER obsolete, use WM_APP

Mike D
  • 2,753
  • 8
  • 44
  • 77
  • 2
    Actually, the standard controls (like static controls, or textboxes) send messages of the range `WM_USER` through `0x7FFF`. They're not actually used by the *system*, just by system controls. (I know, I know, a meaningless distinction for the average programmer, probably, but an important one nonetheless.) More information is [here in the SDK docs](http://msdn.microsoft.com/en-us/library/ms644931.aspx), but you're correct in using `WM_APP + x` for your own private messages. – Cody Gray - on strike Jul 25 '11 at 14:15
  • As far as the precise sequencing of messages, that's generally undocumented for a reason. You aren't supposed to rely on getting messages in any order, other than `WM_NCDESTROY` is *always* the last message that a window will get. Other than that, relying on a precise order is risky because the order might change in a future version of Windows. For a properly-designed app, it really shouldn't matter. If you still have trouble, please update your question with a code sample and I'll be happy to take a look. – Cody Gray - on strike Jul 25 '11 at 14:17
  • @Cody Gray: SendMessage says it doesn't return until the target window has processed the message; that's all I care about for this case. – Mike D Jul 25 '11 at 18:12
  • @Cody Gray: Are the messages generated for example static controls documented anywhere? – Mike D Jul 25 '11 at 18:19
  • Yes, they're listed in the SDK documentation under [Messages](http://msdn.microsoft.com/en-us/library/ff486029.aspx) and [Notifications](http://msdn.microsoft.com/en-us/library/ff486030.aspx). I *think* that's all of them. I'm not sure if there are any undocumented messages that applications are not intended to respond to, but I don't think there are. Notice that all of those messages/notifications will not be sent for every control. Many of them depend on the style flags that you have set. – Cody Gray - on strike Jul 26 '11 at 07:51
  • @Cody Gray: One other question occurs to me. If I'm a uSoft developer of such things or a third party developer of such things, there must be a place/process for registering (I mean a people process, not RegisterWindowMessage) such things. Is there? – Mike D Jul 27 '11 at 10:52
  • Yes, the [`RegisterWindowMessage` function](http://msdn.microsoft.com/en-us/library/ms644947.aspx). But as the docs say, you only need that if you need to communicate between discrete applications, not for creating your own controls and having them communicate with their parent window. As far as some central repository of control message IDs? No. There doesn't need to be one. Microsoft has only documented theirs for your convenience, because you as an app developer might like to respond to them to customize the behavior of the controls. As an ISV, you'd include that information in *your* docs. – Cody Gray - on strike Jul 27 '11 at 10:55
  • I don't understand that! I got in trouble because I was doing just that, creating my own control! Oh, maybe I see, it doesn't have to unique because the control plus msg id are unique; is that the answer? – Mike D Jul 27 '11 at 11:01
  • Right. You have to define unique IDs for your own messages inside of your own code. If you start with `WM_APP` and add numbers to it, they're guaranteed to be unique within your application. But they *won't* necessarily be unique if you expect to send messages to *other* applications because those applications might have used the same offset numbers in their code as you did. In that case, you need to use `RegisterWindowMessage`. I don't think that applies to you in this case. – Cody Gray - on strike Jul 27 '11 at 11:04
  • I understand that. But let's say I am making my own control. Then I can use whatever WM_USER I want because when I send such a message to the parent, the combination of message and control ID=LOWORD(wParam) will be unique. My, you r up early! – Mike D Jul 27 '11 at 11:11
  • I suppose you could. But Microsoft's documentation recommends that you not do that because the standard, built-in controls also use messages with IDs in that range (`WM_USER to `0x7FFF`). If you're creating your own *completely* custom control, then you would be alright. But if you're *superclassing* one of the built-in controls, then you would potentially have a problem if your chosen message ID conflicts with the one the system is already using for the built-in control. I think you're over-complicating this, though. Using `WM_APP + n` should work just fine. – Cody Gray - on strike Jul 27 '11 at 11:16
  • Just trying to understand the principles here. But if I use WM_APP, I step on other peoples's stuff! ENough for now. – Mike D Jul 27 '11 at 11:19