News:

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

Main Menu

Trouble with Common Controls Manifest

Started by Don57, October 22, 2012, 06:01:39 AM

Previous topic - Next topic

Don57

I am trying to load a manifest to upgrade the button and progress bar appearance. Everything appears to assemble alright, but the appearance of the controls is unchanged.

dedndave

the problem seems to be in the MakeIt.bat file
c:\masm32\bin\ml.exe /c /coff LogCleaner.asm rsrc.obj

pause

c:\masm32\bin\link.exe /SUBSYSTEM:WINDOWS LogCleaner.obj


OBJ files are LINK'ed together - not assembled   :P
try removing the rsrc.obj name from the ML line and placing it on the LINK line   :t


dedndave

no problem, Don

i also suggest you execute the InitCommonControlsEx call before you create any windows/controls
most members put it in the startup code, before calling WinMain

hutch--

Don,

Dave has a good point here, if your controls are simple ones you can probably get away with the older API with the line,


    invoke InitCommonControls


If you use the extended API be careful about matching the styles to those used by the application as I have found from experience that some combinations that work fine on my US editions of WinXP SP3 and Win7 64 bit Ultimate do not work on some other language versions. As we have members here from around the world who have tested this it is worth making the effort. Without a manifest it often does not matter but once you use a manifest this matching is important.

Don57

I moved InitCommonControlsEx  now I get an error on assembly.


Log_Scrub:

   LOCAL icce:INITCOMMONCONTROLSEX

      invoke GetModuleHandle,NULL                                              ; get instance handle
      mov    hInstance,eax                                                     ; returned in eax                                                                              ; save in hInstance

      invoke GetCommandLine                                                    ; get  the command line
      mov    CommandLine,eax                                                   ; put pointer incommand line
       
      mov   icce.dwSize, SIZEOF INITCOMMONCONTROLSEX
      mov   icce.dwICC,ICC_PROGRESS_CLASS
      invoke InitCommonControlsEx,addr icce

      invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT             ; start the program
     


LogCleaner.asm(162) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
LogCleaner.asm(172) : error A2006: undefined symbol : icce
LogCleaner.asm(172) : error A2114: INVOKE argument type mismatch : argument : 1
LogCleaner.asm(170) : error A2006: undefined symbol : icce
LogCleaner.asm(171) : error A2006: undefined symbol : icce

Gunner

You cannot use the LOCAL macro to create stack variables without using a PROC.
You are using a label as a procedure, if you want a stack variable, you need to do it manually, or just make icce a global
~Rob

hutch--

Don,

You are trying to allocate a LOCAL that is not inside a PROC.

This makes it build OK, I just added two lines to make it a "main" proc.



Log_Scrub:

main proc

   LOCAL icce:INITCOMMONCONTROLSEX

      invoke GetModuleHandle,NULL                                              ; get instance handle
      mov    hInstance,eax                                                     ; returned in eax                                                                              ; save in hInstance

      invoke GetCommandLine                                                    ; get  the command line
      mov    CommandLine,eax                                                   ; put pointer incommand line
       
      mov   icce.dwSize, SIZEOF INITCOMMONCONTROLSEX
      mov   icce.dwICC,ICC_PROGRESS_CLASS
      invoke InitCommonControlsEx,addr icce

      invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT             ; start the program
                                                                              ; hInstance - module handle
           ;(Registers Windows Class)
           ;(Create Window)                                                     command line pointer
           ;(Show Windows on Desktop)                                           flag that determines how
           ;(Refresh Client Area)                                               window is shown (SW_SH...)
                                                                              ;      from win.inc
      invoke ExitProcess, eax                                                  ; the exit code is returned in
                                                                              ; eax from WinMain

main endp


dedndave

it's an 8-byte structure
it takes more bytes of code to set up the stack frame and initialize the structure
i usually just put it in the .DATA section and pre-initialize it

        .DATA

icc     INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,ICC_PROGRESS_CLASS>

jj2007

Quote from: dedndave on October 23, 2012, 01:50:26 PM
i usually just put it in the .DATA section and pre-initialize it

Dave, how can you waste 6 bytes ::)

   push ICC_PROGRESS_CLASS
   push INITCOMMONCONTROLSEX
   invoke InitCommonControlsEx, esp
   pop ecx
   pop edx


dedndave

 :biggrin:

i remember having this discussion before -  lol
you don't really need to pop the structure off the stack   :P
and - in many cases, no flags at all are required
        push    0
        push    sizeof INITCOMMONCONTROLSEX
        INVOKE  InitCommonControlsEx,esp
;
;
;
        INVOKE  ExitProcess,eax

ExitProcess takes care of the stack clean-up
that gets it down to 10 bytes   :biggrin:

generally, if you are going to add flags, ICC_WIN95_CLASSES will be in there, which is 0FFh
(it includes ICC_PROGRESS_CLASS)
that makes that push 5 bytes instead of 2
adding the pop's back in there for count....
        push    ICC_WIN95_CLASSES
        push    sizeof INITCOMMONCONTROLSEX
        INVOKE  InitCommonControlsEx,esp
        pop     ecx
        pop     edx

that makes 15 bytes

and, of course.....
        .DATA
icc     INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,ICC_WIN95_CLASSES>

        .CODE
        INVOKE  InitCommonControlsEx,offset icc

is 18 bytes

3 bytes isn't worth the headache - lol
when you are done, you have to spend the time to explain to some newbie what the hell is going on
and - if you want to, you can use the .DATA section structure for something else, too
if you do, you are back down to 10 bytes   :biggrin:

hutch--

I see the chase for a few bytes as a "who cares" when the section alignment will almost garrantee that it does not matter. Byte sized optimisations belong back in the 16 bit COM file era and even then it did not matter much.

dedndave


hutch--

 :biggrin:

Yeah, by misleading folks who are learning assembler programming. Years ago I wasted a massive amount of time writing an app called TheGun.Exe, it was 6k and made the point that assembler programming could deliver very small applications but it was hardly a model for general purpose apps.