Hello everybody, I have a general question (maybe this explains, why I am posting in this forum :P ). I have a program that needs several buttons (about 30!!). What would be the best way of creating and checking/reacting on those buttons? Would you just go and create every single button with the button function (PushButton) with saving its handle afterwards by hand (Please note that I am not using dialog resources but "real" windows), maybe with some help of a macro taking all params from/for me and doing in reality the same thing I would do or is there a clever alternative? And for checking the WM_COMMAND: Would you check for every ID of the buttons or can I check them "in a row" (like increasing a value representing the ID every time until I reach the last valid one) and then just check the conditions? This is very important for me, so please reply! Stefan P.S. I didn't want to use a poll because there you can't actively/directly reply but just click a button and other replies under a poll look somehow annoying.
Posted on 2001-03-28 13:51:00 by Stefan Krause
Controls are used as child windows. Child windows get control ID's via the hMenu argument in CreateWindowEx. Control ID's are the reason why child windows cannot have a menu bar. This control ID is the number you would assign to a control in an RC file. With appropriate numbering, control ID's can be the basis for indexing into tables. For example, numbering a set of buttons to have control ID's from 2001 to 2030, allows you to create a table index by subtracting 2001 from the ID. Making the control ID's unique within one parent window allows you to know which control sent a WM_COMMAND -- because WM_COMMAND gives you the ID (the low 16 bits of wParam). WM_COMMAND will also give you the handle of the control in lParam, if you need to send messages to the control. If you simply want to react to the buttons, in your WM_COMMAND handler, test for the control ID's and just write the reaction code. Or use an address table and use an "indexed jump". Does MASM have CASE ? Most likely, you aren't changing the number of buttons while the program is running, so... Don't read the buttons every time you want to summarize. Initialize a table, and change its entries in response to a button click. It's faster and simpler to use the table than to send messages to retrieve button information. If you're making check boxes or radio buttons, change a single table entry when you get a WM_COMMAND from those specific controls. There's no such thing as two selections at one time because you'll get two messages, and you can respond to only one message at a time. If you don't know how to create and use tables/arrays in ASM, that's a separate lesson... This message was edited by tank, on 3/28/2001 8:06:36 PM
Posted on 2001-03-28 18:57:00 by tank
hi stefan, at first i WOULD throw all the button-declarations in a resource file... i think there is no difference between a resource file and declaring all this stuff the "real" way. what happens if you press on of these buttons? i mean if there are different actions depending on what button you pressed you HAVE to check them in row. as i don't know what you want to do exactly i suggest you should declare the button ID's in row, too - this could make it easier to react. oh, another idea: say you've got 30 bottons and every button should execute a different block of code. now i would declare an array of 30 pointer, every pointer should point to one of your procedures. now (if you've got ID's in row) you could do something like this:

if button is pressed:

mov edi,offset pointer_array
add edi,4*30
mov ecx,30
@@bla:
sub edi,4
cmp ax,cx ;ax should contain the buttonID
jz 
loop @@bla
oh my god... now i realized what i wrote, how stupid must someone be who loops 30 comparisations just to jump to a calculatable adress? - it's 4 o' clock in the morning :( ok, here we go:

;...
.ELSEIF     uMsg == WM_COMMAND
            mov eax,wParam
            mov edx,wParam
            shr edx,16         

.IF         dx == BN_CLICKED    

mov edi,offset pointer_array
shl ax,2 ;multiply buttonID with 4 (1 pointer = 4 bytes)
add di,ax
jmp 

;...
note that the buttonID's must be from 0 to 30 in row if your ID's start for example @ 1000 you've to sub 1000 before the "shl" instr! if you want to optimize you can also do this:

mov ebx,offset pointer_array
lea edi, 
;------lea edi, is also possible...
jmp 
excuse me :) This message was edited by drcmda, on 3/29/2001 4:22:44 AM
Posted on 2001-03-28 18:58:00 by drcmda