News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

WS_TABSTOP for Dialogs created with CreateDialogParam

Started by 2B||!2B, November 20, 2018, 04:24:27 PM

Previous topic - Next topic

2B||!2B

Hi,

I need to create a modaless dialog box using CreateDialogParam api but i can not get the WS_TABSTOP to work on this newly created dialog.
This modaless dialog box does not have WS_CHILD style set. If i create it with DialogBoxParam, the WS_TABSTOP will work but i do not want to block the execution of my application.

My main dialog is created with DialogBoxParam using windows default message loop.

Any ideas?



aw27

Call IsDialogMessage for modaless modeless dialogs.

2B||!2B

Hi AW,

Nice way. I think it must be used this way for Modeless dialog boxes that are created with CreateDialogParam
are there any benefits from creating the Main dialog using CreateDialogParam and then add our own message loop with IsDialogMessage?
What is the difference between using this method and using DialogBoxParam (For the parent)?

BTW, for anyone who might have the same issue, here is a nice trick from Microsoft on how to call the IsDialogMessage for multiple modeless dialogs
The link was removed but thanks to archive.org  :icon_mrgreen:

https://web.archive.org/web/20100826033540/http://support.microsoft.com/kb/71450

The trick is to make a global variable that will hold he currently active window handle. And then, the IsDialogMessage will use this handle. Because only one active window can be set at time, the IsDialogMessage will switch for the current active window automatically once you change the global variable for the current active window handle in response to WM_ACTIVATE in each modaless dialog.

aw27

Quote from: 2B||!2B on November 20, 2018, 07:29:22 PM
What is the difference between using this method and using DialogBoxParam (For the parent)?
DialogBoxParam is for modal dialog boxes - this is clearly mentioned in the online reference from Microsoft. So, if you changed your mind, use it.

2B||!2B

AW,

Thanks for your help.

I have one more question:

If i want to get WM_KEYDOWN/WM_KEYUP messages in my modaless dialog box how would i do so?

Because the IsDialogMessage/TranslateMessage convert them to WM_COMMAND and this message does not catch all keystrokes

I managed to add a filter before passing the message to translation with the above API's and then examine the message and if the message is WM_KEYDOWN/WM_KEYUP, i will pass it to the corresponding window directly using SendMessage and skip the message translation part.

Example for message loop:

    .WHILE TRUE
Skip:
        invoke GetMessage, addr msg, NULL, 0, 0
       
        .BREAK .if !eax
        .if msg.message == WM_KEYDOWN || msg.message == WM_KEYUP
       
        invoke SendMessage,CurrentActiveDialog,msg.message,msg.wParam,msg.lParam
        JMP Skip
        .endif
        invoke IsDialogMessage, CurrentActiveDialog, addr msg
       
        .if EAX == 0

        Invoke TranslateMessage, addr msg
            Invoke DispatchMessage, addr msg
        .endif
       
    .ENDW


Is there something wrong by doing this?

Because i want to catch all pressed keystrokes, if i don't look for WM_KEYDOWN/WM_KEYUP, the keystroke will come as a WM_COMMAND but the problem here is that this message does not provide all keystrokes (for example, the CTRL or SHIFT are never delivered)


aw27

I would suggest you to start a new thread for each new question because I rather prefer to answer only the questions I freely choose to.

Only for this one, you can't forget that a modeless dialog has its own message loop and certain types of messages, including WM_KEYDOWN and WM_KEYUP are directed to that message loop whenever the dialog has the focus.

2B||!2B

Quote from: AW on November 21, 2018, 07:05:40 PM
I would suggest you to start a new thread for each new question because I rather prefer to answer only the questions I freely choose to.

Fair enough.

For the last code i posted about fetching WM_KEYDOWN, it is not recommended to do so because that will break any chars from being entered into an edit control. You have to add a check and not skip translating WM_KEYDOWN if an edit control has the focus.

jj2007

Quote from: 2B||!2B on November 23, 2018, 06:52:28 AMfetching WM_KEYDOWN, it is not recommended to do so because that will break any chars from being entered into an edit control.

Who says that?

hutch--

Its usually the case that an edit or richedit control uses its own subclass procedure to process messages which you either allow to be default processed OR modified OR thrown away if it is used as a trigger for an event.

2B||!2B

Quote from: jj2007 on November 23, 2018, 07:55:50 AM
Quote from: 2B||!2B on November 23, 2018, 06:52:28 AMfetching WM_KEYDOWN, it is not recommended to do so because that will break any chars from being entered into an edit control.

Who says that?

Try it jj, you will see that the text won't be entered in an edit control.

.WHILE TRUE
Skip:
        invoke GetMessage, addr msg, NULL, 0, 0
       
        .BREAK .if !eax
        .if msg.message == WM_KEYDOWN || msg.message == WM_KEYUP
       
        invoke SendMessage,CurrentActiveDialog,msg.message,msg.wParam,msg.lParam
        JMP Skip
        .endif
        invoke IsDialogMessage, CurrentActiveDialog, addr msg
       
        .if EAX == 0

        Invoke TranslateMessage, addr msg
            Invoke DispatchMessage, addr msg
        .endif
       
    .ENDW


The weird thing is that this only happens if you use the default class dialog. If you create a custom class dialog (use RegisterClass etc) it will work and you will receive WM_KEYDOWN/WM_KEYUP without the need to trap the message after GetMessage. Maybe that's because we are providing the WndProc callback ourselves?


Quote from: hutch-- on November 23, 2018, 10:22:33 AM
Its usually the case that an edit or richedit control uses its own subclass procedure to process messages which you either allow to be default processed OR modified OR thrown away if it is used as a trigger for an event.

That is true. If we subclass the control then we can get WM_KEYDOWN without problem.

jj2007

        .if msg.message == WM_KEYDOWN || msg.message == WM_KEYUP
        invoke SendMessage,CurrentActiveDialog,msg.message,msg.wParam,msg.lParam
        JMP Skip
        .endif


Since you didn't post a complete example, and since I am far too lazy to write one around your few lines, I can only guess what will happen if you check also for the wParam, and allow the SendMessage, CurrentActiveDialog only for wParams that you want to see processed.

2B||!2B

Quote from: jj2007 on November 23, 2018, 06:52:51 PM
        .if msg.message == WM_KEYDOWN || msg.message == WM_KEYUP
        invoke SendMessage,CurrentActiveDialog,msg.message,msg.wParam,msg.lParam
        JMP Skip
        .endif


Since you didn't post a complete example, and since I am far too lazy to write one around your few lines, I can only guess what will happen if you check also for the wParam, and allow the SendMessage, CurrentActiveDialog only for wParams that you want to see processed.

Hi jj,

Sorry for late reply.
The project is just a template using RadASM DialogAsMain.
I have found the issue. We must never use SendMessage to skip translate of message. Instead, we only need to skip IsDialogMessage on the desired message if we want to get the WM_KEYDOWN/WM_KEYUP instead of the traditional WM_COMMAND.

But if the message was generated for a control, it must have its own window callback.That is, subclassed. Otherwise, the system will just send you a WM_COMMAND contains the control's info whether you called IsDialogMessage on the message or not.
It works this way i have tested it.