flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > Center MessageBox in Parent Window, Win64

Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 4020
Location: vpcmpistri
bitRAKE 28 Mar 2013, 14:25
Who (besides Microsoft) doesn't want to center MessageBox's on the Window generating them?

I'm watch a movie on my primary monitor, and working on the secondary. "Beep!" WTF? My application appears to be frozen. Searching all over the screens. Thinking, "What stopped, huh?" Then under my movie is a MessageBox. Or, worse - hitting enter and not knowing what caused the MessageBox.

Clearly, there are times when MessageBox's don't logically result from a user's action. Yet, if the user is focused on your application and has caused an error/alert by their action, then the MessageBox should be put at their point of focus. It's just good UI design and respectful to the user.

Here is the routine that lets you do that, a CBT Hook which is only momentarily active. Simply replace:

    invoke MessageBox,[hWnd],[lpText],[lpCaption],[uType]

with:
    fastcall CBTMessageBox,[hWnd],[lpText],[lpCaption],[uType]


...and include this code:
Code:
; (somewhere in your global bss/data? segment)
hHk rq 1 ;CBT HHOOK
.
. ( in the code segment )
.
proc CBTMessageBox,hWnd,lpText,lpCaption,uType
        mov [hWnd],rcx
        mov [lpText],rdx
        mov [lpCaption],r8
        mov [uType],r9
        invoke GetCurrentThreadId
        invoke SetWindowsHookEx,WH_CBT,CBTProc,0,rax
        mov [hHk],rax ; doesn't matter if it fails, we need to continue
        invoke MessageBox,[hWnd],[lpText],[lpCaption],[uType]
        ret
endp

proc CBTProc nCode,hChild,lpCBTact
    locals
        rParent RECT
        rChild RECT
    endl

        cmp ecx,HCBT_ACTIVATE
        jz .HCBT_ACTIVATE
        invoke CallNextHookEx,[hHk],rcx,rdx,r8
        xor eax,eax
        ret
.HCBT_ACTIVATE:
        mov [hChild],rdx
        invoke GetWindowRect,rdx,addr rChild
        test eax,eax
        jz @F
        invoke GetParent,[hChild]
        test eax,eax
        jz @F
        invoke GetWindowRect,rax,addr rParent
        test eax,eax
        jz @F
        mov r9d,[rChild.right]
        mov eax,[rChild.bottom]
        mov edx,[rParent.right]
        mov r8d,[rParent.bottom]
        sub r9d,[rChild.left] ; width
        sub eax,[rChild.top] ; height
        add edx,[rParent.left]
        add r8d,[rParent.top]
        sub edx,r9d
        sub r8d,eax
        sar edx,1 ; start.x
        sar r8d,1 ; start.x
        invoke MoveWindow,[hChild],rdx,r8,r9,rax,FALSE
;
; any error results in unhooking and just presenting without centering
;
    @@: invoke UnhookWindowsHookEx,[hHk]
        xor eax,eax
        ret
endp    
...and if you are curious to see it in action, check out this example.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 28 Mar 2013, 14:25
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.