Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29275 Discussions

Customizing dialog box colors using subclassing: reprise2

TommyCee
Beginner
526 Views

This is in response to this thread:

http://software.intel.com/en-us/forums/showthread.php?t=71059

I tried to reply to it ('Reply to #2') but got no reply window to appear! Perhaps SLionel could investigate.

I appreciate DannyCat's 01/09/10 suggestion:

"Please refer to a similar thread that I instigated"Changing Text Colours/Fonts in dialog controls" dated April 11th 2009."

but didn't find the informaton of particular use (to my problem).

I read your 2 posts, Anthony (and saw the 1st one posted w/ your article on tab colorization). I saw your jpeg rendering and agree that you seem to have accomplished (using your subclassing apparatus) what I'm after. Kudos! And I'm not terribly concerned that the tabs themselves aren't colored. Given the hassle involved in coloring them (you mentioned OwnerDraw, etc.) I can probably live with then as they are.

I wish I had your code to peek at - it might give me an idea as to what I'm doing wrong. Could you please post it?

When I said this in my reply (your colorization post):

[bash]hBackBrush = 0
lret = DlgInit(IDD_DIALOG, Dlg)

!Initialize the tab dialog boxes:
lret = DlgInit(IDD_ONE, Dlg_Tab1)
lret = DlgInit(IDD_TWO, Dlg_Tab2)
lret = DlgInit(IDD_THREE, Dlg_Tab3)
lret = DlgInit(IDD_FOUR, Dlg_Tab4)
...
!Set the Dlg colors:
lret = DlgSetSub(Dlg, IDD_Dialog, BackColorSub)
lret = DlgSetSub(Dlg_Tab1, IDD_ONE, BackColorSub)
lret = DlgSetSub(Dlg_Tab2, IDD_TWO, BackColorSub)
lret = DlgSetSub(Dlg_Tab3, IDD_THREE, BackColorSub)
lret = DlgSetSub(Dlg_Tab4, IDD_FOUR, BackColorSub)

ret = DlgModal(Dlg) !Activate the Main Dialog box[/bash]

Get this:

A) If only the 1st of the 5 lines above is active (other 4 commented out), the Dialog that subtends the Tab Control is properly colored.
B) If the 1st line is commented out and the remaining 4 lines are active, each tab is colored correctly.

my description for (A) omitted the best part. It should have read:

A) If only the 1st of the 5 lines above is active (other 4 commented out), the Dialog that subtends the Tab Control is properly colored BUT ALL STATIC BOXES AND CONTTROLS INSTALLED ON THE TAB ARE MISSING (DISAPEARED).

Once I comment out only the 1st line, all reappears fine (just no color). I only mention this in the hope it might hint at what's wrong.

You suggested that I post my code. Ordinarily I would be OK w/ that but in this case, the code I'm dealing with may be proprietary. If I had your private e-mail address, I'd be glad to provide it (your call). What might help is if you could please attach the code that resulted in your jpeg image and I could stare at that.

I'm open to other suggestions, and appreciate your help.

TC

0 Kudos
4 Replies
anthonyrichards
New Contributor III
526 Views

At the momentI am away from the machine that I developed my test program on, so cannot post my code yet.

However, whatI can say is

1) I use seperate call-back subroutines for each dialog when using DlgSetSub

2) I use seperate dialog procedures for each dialog when I subclass each one from within the seperate dialog call-back routines.

This allows me to more easily keep track of the message loops involved. I observe that you are using the same call-back subroutine for all your dialogs. This means that you must have a selection on the dialog handle within the call-back somewhere so that you can subclass the appropriate dialog when the call-back routine is called on initialising each dialog using DlgInit. Perhaps there is a bug within this part of your code.

Do you also use a single dialog procedure for all your dialogs when you subclass? This could also be a source of confusion unless very carefully done.

The absence of controls on a dialog could indicate that the default dialog procedure has been replaced (sub-classed) but the replacement procedure is not properly processing the WM_CTLCOLOR... messages for that particular dialog, or not passing all other messages on to the default dialog procedure correctly.

Perhaps the replacement procedure's address you are using is wrong? Try commenting out your code for processing the WM_CTLCOLOR... messages and insert calls to pass each WM_CTLCOLOR... message on to the default dialog procedure using CallWindowProc and see if the controls reappear. If this happens, then you prove that the sub-classing works but the replacement code has bugs.

0 Kudos
TommyCee
Beginner
526 Views

Thanks for your thoughts, Anthony.

As for your:

1) I use seperate call-back subroutines for each dialog when using DlgSetSub

I do exactly this, as I demonstrate in the code snippet I posted (above).

And as for your:

2) I use seperate dialog procedures for each dialog when I subclass each one from within the seperatedialog call-back routines.

This sounds like a good idea, and is exactly what I was thinking of when, in responding to you colorization post:

http://software.intel.com/en-us/articles/how-to-customize-dialog-box-colors-using-subclassing/

I wrote:

I) I was able to integrate your logic (routines) into my app and had success - at least so far. In may case, thought (and very much NOT like in your DEMO), I have several Dialogs that get launched. Your routine - in the callback sequence BackColorSub -> MyDlgProc - seems to treat them all the same (i.e., there is no discrimination). What if one wanted to color one Dlg red, and (elsewhere in the program) another Dlg blue. I wish that an other parameter (tag) could be passed in the callback linkage so that when MyDlgProd in called, a decision could be made when it hits the Dialog branch as to how to handle the colorization scheme. Does this make any sense?

In order to differentiate parts within MyDlgProc, it seems that some kind of "tag" must be passed in the call to BackColorSub, e.g.,

lret = DlgSetSub(gDlg, IDD_BACKCOLOR_DIALOG, BackColorSub)

, with continuity to the call to MyDlgProcl. e.g.,:

hDlgProc = SetWindowLong(hDlg, DWL_DlgProc, LOC(MyDlgProc))

so that, when MyDlgProc gets it, it knows how to route control and have the right kind of processing happen. In other words, there might be a CASE cascade at the top of MyDlgProc that routes control to a particul/ar part of MyDlgProc, depending on where the call came from.

Let me go out on a limb here:


The logic sequence might look like this (this is just a sketch):

integer :: iRef !An arbitrary integer that represents from where the call originates.

Lret = DlgSetSub(gDlg, IDD_BACKCOLOR_DIALOG, BackColorSub, iRef)

Sub. BackColorSub (Dlg, id, callbacktype, iRef)

integer :: iRef

hDlgProc = SetWindowLong(hDlg, DWL_DlgProc, LOC(MyDlgProc), iRef)

End Sub. BackColorSub

function MyDlgProc(hDlg, message, wParam, lParam, iRef)

CASE cascade to dispose of the call based on its origin (the value of iRef)

end function MyDlgProc

Does any of this make any sense?

You wrote:

This allows me to more easily keep track of the message loops involved. I observe that you are using the same call-back subroutine for all your dialogs. This means that you must have a selection on the dialog handle within the call-back somewhere so that you can subclass the appropriate dialog when the call-back routine is called on initialising each dialog using DlgInit.

I think the key is here:

"This means that you must have a selection on the dialog handle within the call-back somewhere ..."

But I didn't see any parameterization using a tag (e.g., my iRef) in your original colorization code (and I studied it thoroughly).

Am I tracking you at all? What am I missing?


{P.S. I'm not sure what "Mark this post Private?" really means. If 'Yes', does this mean my reply only routes to (is accessible by) you? Just curious ...

0 Kudos
anthonyrichards
New Contributor III
526 Views

The first point I madewas that you use the SAME call-back routine, BackColorSub, for each dialog. I use a different one for each dialog. Since your BackColorSub is called when each of the 4 or so dialogs are initialised, and since its arguments are BackColorSub (Dlg, id, callbacktype, iRef) in order to treat the dlg_init callbacktype differently for each individual dialogthat calls it, there has to be code to test for the handle (Dlg%Hwnd) of the particular dialog for which this particular call-back is being made, so that the subclassing can be carried out correctly for each dialog. This means storing each dialog handle somewhere, I presume, so that it is ready to be compared to the dlg%hwnd dialog handle for a particular call to BackColorSub. This should be done after the DlgInit that initialises a dialog. My approach requires a unique BacColorSub (BackColorSub1, ...Sub2,etc.)and a unique MyDlgProc (MyDlgProc1, ...Proc2 etc.)for each dialog I use, to avoid confusion. It means more code, but I think it is a better approach during initial code development. Once you have each dialog correctly subclassed, you can start developing the code to handle WM_CTLCOLR... messages for each dialog seperately in each seperate MyDlgProc procedure, so that you cannot screw up one dialog when trying to process messages forone of the otherdialogs.

0 Kudos
TommyCee
Beginner
526 Views

Anthony,

I finally get your point. You use TWO different calling subroutines (e.g., BackColorSub1 & BackColorSub2) and - respectively - TWO different MyDlgProcs. I applied that concept to my system and still have the trouble I reported before (I either get the Main Dialog to colorize (and the tabs are UNcolored and their controls disappeared) , or I get the tabs to colorize but the Main Dlg (in the background) is UNcolorized.)

Recall you provided a jpeg proof of your result here:

http://software.intel.com/en-us/forums/showthread.php?t=71059&o=d&s=lr

Would you be please be so kind as to post your source code for this demo so I can trace your procedure?

0 Kudos
Reply