flat assembler
Message board for the users of flat assembler.
Index
> Windows > Help with menus |
Author |
|
wisepenguin 27 Feb 2006, 16:54
from memory use GetWindowRect to get the coordinates and position of the button
pass rect.bottom for the y parameters and rect.left for the x check what each function uses in terms of coordinates (screen/client) |
|||
27 Feb 2006, 16:54 |
|
Reverend 27 Feb 2006, 18:23
- GetCursorPos
- ChildWindowFromPoint - GetWindowRect - some_smart_calculations - TrackPopupMenu |
|||
27 Feb 2006, 18:23 |
|
ManOfSteel 01 Mar 2006, 20:11
Hello,
I tried what wisepenguin proposed, but was unfortunately unable to make it work. I have programmed DOS assembler with TASM then NASM for years, but I am rather new to Win32ASM and FASM, so I may do some silly things. By the way, can structures be used with FASM? Below is the code. I would appreciate your help in finding the error(s). Thank you in advance. Code: format PE GUI 4.0 entry start include '\fasmw164\INCLUDE\win32ax.inc' include '\fasmw164\INCLUDE\apia\kernel32.inc' include '\fasmw164\INCLUDE\apia\user32.inc' section '.data' data readable writeable winclass db 'TestClass',0 hPopupMenu dd 0 ButtonRect dd 0 dd 0 dd 0 dd 0 wc WNDCLASS 0,WindowProc,0,0,0,0,0,COLOR_BTNFACE+1,0,winclass msg MSG section '.code' code readable executable start: invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc invoke LoadMenu,[wc.hInstance],0 invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,winclass,'Test',WS_VISIBLE+WS_OVERLAPPEDWINDOW,0,0,200,200,0,eax,[wc.hInstance],0 msg_loop: invoke GetMessage,msg,0,0,0 or eax,eax jz end_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop end_loop: invoke ExitProcess,[msg.wParam] proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi cmp [wmsg],WM_CREATE je wmcreate cmp [wmsg],WM_DESTROY je wmdestroy cmp [wmsg],WM_CLOSE je wmdestroy cmp [wmsg],WM_COMMAND je wmcommand defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp finish wmcreate: invoke CreateWindowEx,0,'BUTTON','TestButton',WS_CHILD+WS_VISIBLE,10,10,80,24,[hwnd],200,[wc.hInstance],0 invoke CreatePopupMenu mov [hPopupMenu],eax invoke AppendMenu,[hPopupMenu],MF_STRING,300,'Item &1' invoke AppendMenu,[hPopupMenu],MF_STRING,301,'Item &2' xor eax,eax jmp finish wmdestroy: invoke PostQuitMessage,0 xor eax,eax jmp finish wmcommand: mov eax,[wparam] cmp eax,200 je ChannelButtonCommand jmp wmcommandend ChannelButtonCommand: invoke GetWindowRect,200,ButtonRect invoke TrackPopupMenu,[hPopupMenu],TPM_RIGHTALIGN,[ButtonRect],[ButtonRect+12],0,[hwnd],0 jmp wmcommandend wmcommandend: xor eax,eax jmp finish finish: pop edi esi ebx ret endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',user32,'USER32.DLL' |
|||
01 Mar 2006, 20:11 |
|
vbVeryBeginner 02 Mar 2006, 08:36
check this man of steel :p
Code: format PE GUI 4.0 entry start include '%fasminc%\win32ax.inc' section '.data' data readable writeable winclass db 'TestClass',0 hPopupMenu dd 0 ButtonRect RECT button.h dd ? wc WNDCLASS 0,WindowProc,0,0,0,0,0,COLOR_BTNFACE+1,0,winclass msg MSG section '.code' code readable executable start: invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc invoke LoadMenu,[wc.hInstance],0 invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,winclass,'Test',WS_VISIBLE+WS_OVERLAPPEDWINDOW,100,100,200,200,0,eax,[wc.hInstance],0 msg_loop: invoke GetMessage,msg,0,0,0 or eax,eax jz end_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop end_loop: invoke ExitProcess,[msg.wParam] proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi cmp [wmsg],WM_CREATE je wmcreate cmp [wmsg],WM_DESTROY je wmdestroy cmp [wmsg],WM_CLOSE je wmdestroy cmp [wmsg],WM_COMMAND je wmcommand defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp finish wmcreate: invoke CreateWindowEx,0,'BUTTON','TestButton',WS_CHILD+WS_VISIBLE,10,10,100,24,[hwnd],200,[wc.hInstance],0 mov [button.h],eax invoke CreatePopupMenu mov [hPopupMenu],eax invoke AppendMenu,[hPopupMenu],MF_STRING,300,'Item &1' invoke AppendMenu,[hPopupMenu],MF_STRING,301,'Item &2' xor eax,eax jmp finish wmdestroy: invoke PostQuitMessage,0 xor eax,eax jmp finish wmcommand: mov eax,[wparam] cmp eax,200 je ChannelButtonCommand jmp wmcommandend ChannelButtonCommand: ;invoke GetWindowRect,200,ButtonRect invoke GetWindowRect,[button.h],ButtonRect ; we get screen cordinate in ButtonRect ; assume u want TPM_LEFTALIGN + TPM_TOPALIGN mov eax,[ButtonRect.left] mov edx,[ButtonRect.bottom] invoke TrackPopupMenu,[hPopupMenu],TPM_LEFTALIGN+TPM_TOPALIGN,eax,edx,0,[button.h],0 jmp wmcommandend wmcommandend: xor eax,eax jmp finish finish: pop edi esi ebx ret endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',user32,'USER32.DLL' include '%fasminc%\apia\kernel32.inc' include '%fasminc%\apia\user32.inc' |
|||
02 Mar 2006, 08:36 |
|
Crukko 02 Mar 2006, 08:53
Remember:
1. Store the handle of the button 2. use it to find the x, y 3. Track the Menu vbVeryBeginner: This was my solution too |
|||
02 Mar 2006, 08:53 |
|
ManOfSteel 03 Mar 2006, 10:34
Thank you very much, that is exactly what I wanted.
But I still have a problem/question. Just imagine that the program lets the user add buttons at will, with, let us say some menu command. Now, in the program you corrected, you suggest to save the button handle, but how can you save the handle of each button the user has created and then how can you know which button was clicked so that you can retrieve the right handle? Right now, handles of old buttons get crushed by the handles of new buttons, so if you add new buttons, when you click any (old) button, the menu obviously only appears below the last one created. So, do you have any idea on how I could store all the handles of all the buttons the user creates, and then retrieve the right one when any button is clicked? Or better... is there any way to automatically retrieve the handle of any button without storing any handle? In other words, is there any API(s) I can invoke that will detect what button was clicked and automatically retrieve and store its handle at a precise memory location? |
|||
03 Mar 2006, 10:34 |
|
Crukko 04 Mar 2006, 08:57
You can find the Button Handle in 'lparam'
invoke GetWindowRect,[lparam],ButtonRect ; we get screen cordinate in ButtonRect so every time you get the exact x, y of the clicked button. If you want to store every button you can create/reserve memory for it Remeber: in the line invoke CreateWindowEx,0,'BUTTON','TestButton',WS_CHILD+WS_VISIBLE,10,10,100,24,[hwnd],200,[wc.hInstance],0 You use the ButtonID=200, so at line cmp eax,200 you find its message.... so 1. Reserve memory 2. use Dword for ButtonID created or handle of the button + Dword handle menu created 3. find the right button handle in the Mem 4. get the handle menu 5. show the menu If the user delete the button simply mov dword 0 into the corresponding memory Hope this will be ok. |
|||
04 Mar 2006, 08:57 |
|
ManOfSteel 05 Mar 2006, 01:29
So, the handle can be retrieved from lparam and the ID can be retrieved as easily from the low-word of wparam, but there is still a problem: while the Windows-generated handle is different for each button, the ID is always the same (200 in the example) unless I am missing something here.
The result here is that we can get the handle to use it with GetWindowRect as you said, but if one of the menu items uses, let us say, SetDlgItemText to change the button caption, we will need the ID (200 invariably for all the buttons) and not the handle, so even though the menu will be correctly shown under the button we click, only the first button caption will be modified when the menu item is clicked. So we still have a problem, unless there is some way to dynamically increase the ID before creating a new button. |
|||
05 Mar 2006, 01:29 |
|
Crukko 05 Mar 2006, 23:01
Siply use:
Code: ButtonID dd 0 CreateWindowEx,0,'BUTTON','TestButton',WS_CHILD+WS_VISIBLE,10,10,100,24,[hwnd], [ButtonID], [wc.hInstance], 0 Remember to increase the ButtonID. Now you have different ID for each button you create. Remember to put it in the memory you reserved |
|||
05 Mar 2006, 23:01 |
|
ManOfSteel 07 Mar 2006, 18:44
Of course! I had already tried something like that but it did not work because I had made an error. But now it works like a charm.
Thank you for all your help, it was very valuable. |
|||
07 Mar 2006, 18:44 |
|
Picnic 10 Mar 2008, 19:41
hi guys,
How to show up & symbol as is? Code: menuitem 'Up & Down',IDM_LEVEL5 |
|||
10 Mar 2008, 19:41 |
|
wisepenguin 10 Mar 2008, 19:57
hi thimis,
Code: menuitem "Up && Down", IDM_LEVEL5 have a good day |
|||
10 Mar 2008, 19:57 |
|
Picnic 10 Mar 2008, 20:04
Oh Gosh, i didn't try this, thank you wisepenguin, have a nice day too.
|
|||
10 Mar 2008, 20:04 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.