News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Button array creation problem

Started by Dogim, January 11, 2011, 09:17:00 PM

Previous topic - Next topic

Dogim

Hallo / good Morning/Day/Night to all.
I'm trying to recreate an example i saw in the Petzold book, but with my own imagination of course, so far i have managed to get the code working without  errors ( so i hope  :toothy) , but I'm stuck with two items.
I don't know how to extract  the Button style from the structure so it can be pushed as a argument before the CreateWindowEx call.
The buttons are displayed however, but the button text are not being displayed the way it should.
my structure looks like thisbutton items <BS_PUSHBUTTON,"PUSHBUTTON">
items <BS_DEFPUSHBUTTON,"DEFPUSHBUTTON">
items <BS_CHECKBOX,"CHECKBOX">
items <BS_AUTOCHECKBOX,"AUTOCHECKBOX">
items <BS_RADIOBUTTON,"RADIOBUTTON">
items <BS_3STATE,"3STATE">
items <BS_AUTO3STATE,"AUTO3STATE">
    items <BS_GROUPBOX,"GROUPBOX">
items <BS_AUTORADIOBUTTON,"AUTORADIO">
items <BS_OWNERDRAW,"OWNERDRAW">

The buttons are being created in WM_MESSAGE,CMP D[uMsg],WM_CREATE
JNE >> .WM_CLOSE
MOV d[cxBtn],10
MOV d[cyBtn],50
LEA EDI,button ; get adres of struct
MOV d[Height_Btn],40 ; height
MOV d[width_Btn],153 ; width
XOR ECX,ECX ; zero counter
XOR EDX,EDX
MOV ESI,ADDR hWndBtn
;button_creation_loop:
L1:
PUSH ECX
PUSH  0 ;
PUSH    [hInstance] ;hInstance,
PUSH    0 ;HMENU hMenu,
PUSH    [hWnd] ;hWndParent,
PUSH    [Height_Btn]    ;int nHeight,
PUSH    [width_Btn] ;int nWidth,
PUSH  [cyBtn]      ;int y,
PUSH    [cxBtn] ;int x,
LEA EAX,d[EDI+items.iStyle] ; get addr style
PUSH    WS_CHILD | WS_VISIBLE| BS_DEFPUSHBUTTON ;DWORD dwStyle,

LEA EBX,d[EDI+items.szText] ;Get addr WindowName

PUSH    EBX ;LPCTSTR lpWindowName,
PUSH 'BUTTON' ;LPCTSTR lpClassName,
PUSH 0 ;DWORD dwExStyle,
CALL CreateWindowEx
POP ECX
MOV [ESI+ECX*4],EAX ; save handle
ADD d[cyBtn],70 ; increase y coord: for next button
INC ECX ; increment counter
ADD EDI,4 ; Point to next item
CMP ECX,10 ; how many times we loop ;
JNZ L1 ; loop
:
JMP >>.EXIT

To see the buttons being created i have to ad a Button style to the PUSH    WS_CHILD | WS_VISIBLE| BS_DEFPUSHBUTTON ;DWORD dwStyle, line.
When i do this PUSH    WS_CHILD | WS_VISIBLE| EAX ;DWORD dwStyle,, the buttons does not show.
Any help in the right direction would much be appreciated.
Full source code included.

xandaz

   Well.... I havent really tested your example but i saw some things that seem wrong. FA: where you put ADD EDI,4 to point to next item you should have ADD EDI,sizeof items, because you 40 byte duplicate after the ButtonStyle. Also i didn't see the InitCommonControls invoke. Did i miss that? You need to do this dispite the comctl32 includes. Here goes an example that i made for you. I hope it does all the things you want.

Dogim

Quote from: xandaz on January 11, 2011, 11:11:25 PM
   Well.... I havent really tested your example but i saw some things that seem wrong. FA: where you put ADD EDI,4 to point to next item you should have ADD EDI,sizeof items, because you 40 byte duplicate after the ButtonStyle. Also i didn't see the InitCommonControls invoke. Did i miss that? You need to do this dispite the comctl32 includes. Here goes an example that i made for you. I hope it does all the things you want.
Thankx for the example Xandaz, i,m going to take a look at your code, to compare and learn from your code, thanks. :U

Dogim

First of all a nice example, liked the simplicity you used for storing the handles, with stosd,  :cheekygreen:,did not see that one, got to learn those mnemonics :wink
Quote from: xandaz on January 11, 2011, 11:11:25 PM
FA: where you put ADD EDI,4 to point to next item you should have ADD EDI,sizeof items
FIXED

Quote from: xandaz on January 11, 2011, 11:11:25 PM
Also i didn't see the InitCommonControls invoke. Did i miss that?
Yes it's  a Donkey template, so it's in there , i have been warned before about this API :red
Found a extra info on MSDN where is  says
QuoteRegisters and initializes certain common control window classes. This function is obsolete. New applications should use the InitCommonControlsEx function.

MSDN
Does this means that i should use the new InitCommonControlsEx ?

xandaz

   Well.... it's not really obsolete. You can use it, but, the InitCommonControlsEx allows you to initialise only the part of the common controls you want to use. In this dwICC of INITCOMMONCONTROLSEX stuct would be ICC_STANDARD_CLASSES. Always glad to return the help others constatelly give to me. So, if you have questions we'll be here for you. Bye Dogim

donkey

InitCommonControls initialiazes the ICC_WIN95_CLASSES group of common controls, for any added after those you will have to use InitCommonControlsEx. Those that are not loaded by InitCommonControls are:

ICC_INTERNET_CLASSES, ICC_PAGESCROLLER_CLASS, ICC_NATIVEFNTCTL_CLASS, INFOTIPSIZE, ICC_STANDARD_CLASSES and ICC_LINK_CLASS

I think that I will change the templates to InitCommonControlsEx, it is the correct function to be using.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Dogim

Quote from: xandaz on January 12, 2011, 07:45:03 PM
   Well.... it's not really obsolete. You can use it, but, the InitCommonControlsEx allows you to initialise only the part of the common controls you want to use. In this dwICC of INITCOMMONCONTROLSEX stuct would be ICC_STANDARD_CLASSES. Always glad to return the help others constatelly give to me. So, if you have questions we'll be here for you. Bye Dogim
Thanks for the help Xandaz  :U

Quote from: donkey on January 12, 2011, 08:36:34 PM
InitCommonControls initialiazes the ICC_WIN95_CLASSES group of common controls, for any added after those you will have to use InitCommonControlsEx. Those that are not loaded by InitCommonControls are:

ICC_INTERNET_CLASSES, ICC_PAGESCROLLER_CLASS, ICC_NATIVEFNTCTL_CLASS, INFOTIPSIZE, ICC_STANDARD_CLASSES and ICC_LINK_CLASS

I think that I will change the templates to InitCommonControlsEx, it is the correct function to be using.
Ill be using the Ex from now on thanks Donkey and Xandaz.

donkey

Hi Dogim,

Here are the templates redone to use InitCommonControlsEx. It will initialize all classes available to comctl32 up to but not including version 6. Since version 6 requires a manifest including the SysLink control would have caused the API to fail on applications without a manifest. So for any CC6+ controls you will have to add them yourself. I just pushed the raw data onto the stack directly from the invoke rather than consuming a label so the call looks like this.

invoke InitCommonControlsEx,offset <8,0,0,0,0xFF,0x3F,0,0>

Should you include a manifest for CC6 you have only to change the 0x3F to 0xFF

All templates that could use it have had it added, just overwrite the templates in RadAsm\GoAsm\Templates (note that these are for RadAsm version 3 only !)

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Dogim

Thanks Donkey
I do however have a dumb question ???
How do i check the version ??
I,m not shure about the version i,m using,because my manifest file looks like this.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="Company.Product.Name"
type="win32"
/>
<description></description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

donkey

#9
Hi Dogim,

Your manifest is for version 6:

type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"


I use the following to check versions at runtime:

GetVersionString FRAME pApplication,pszVersion
uses edi,ebx,esi
LOCAL Verification :D
LOCAL pVersion :%PTR
LOCAL pVersionLen :%PTR
LOCAL hlib :%HANDLE

invoke SetLastError,0

xor ebx,ebx

invoke GetFileVersionInfoSize,[pApplication],OFFSET Verification
test eax,eax
jz >>.ERROR

push eax
invoke GlobalAlloc,040h,eax
mov ebx,eax
pop eax
invoke GetFileVersionInfo,[pApplication],0,eax,ebx
invoke VerQueryValue,ebx,"\",OFFSET pVersion,OFFSET pVersionLen
test eax,eax
jz >>.ERROR

mov esi,[pVersion]
mov eax,[esi+VS_FIXEDFILEINFO.dwFileVersionMS]
mov ecx,eax
and ecx,0FFFFh ;Version.MajorLow
shr eax,16
mov edx,eax ;Version.Major

mov eax,[esi+VS_FIXEDFILEINFO.dwFileVersionLS]
mov edi,eax
and edi,0FFFFh ;Version.MinorLow
shr eax,16 ;Version.Minor

push edx,ecx,eax

cmp D[pszVersion],0
je >
invoke wsprintf, [pszVersion], "%d.%d.%d.%d", edx, ecx, eax, edi
add esp,24
:

invoke GlobalFree,ebx
pop eax,ecx,edx

ret

.ERROR
test ebx,ebx
jz >
invoke GlobalFree,ebx
:
cmp D[pszVersion],0
je >
invoke lstrcpy,[pszVersion],"0.0.0.0"
:
invoke SetLastError,13
xor edx,edx
xor eax,eax
xor ecx,ecx
dec eax
ret

ENDF


Pass the function the NULL terminated name of the DLL and a pointer to a buffer to hold the version string. It will return the version number in EDX:ECX:EAX. For example if you are using comctl32.dll version 5.82.6002.18305, you would invoke as follows:

invoke GetVersionString,"comctl32.dll",offset Somestring

After it executes Somestring would contain "5.82.6002.18305" and the registers would contain
EDX=5
ECX=82
EAX=6002

The build is not returned in the registers (there are only 3 I dared use).


As a side note you can also use the following to initialize common controls, it does not use any DATA or CONST section memory, simply the stack:

invoke InitCommonControlsEx,esp,8,0x3FFF
add esp,8


A pretty elegant method that I may put in the templates eventually.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Dogim

Thank you very much for your help and explanation.