Author Topic: [First timer]Window will not show up  (Read 23683 times)

carre89

  • Guest
[First timer]Window will not show up
« on: November 21, 2012, 07:33:52 AM »
I am building off of this post's code,

http://masm32.com/board/index.php?PHPSESSID=c82e3b3915438fd51115a3e79ba09ae8&topic=205.0

I am trying to run my program in visual studio 2010 but it seems that I the window will not show up. Here's my code:

main.asm

Code: [Select]
TITLE Windows Application                   (WinApp.asm)

; This program displays a resizable application window and
; several popup message boxes.
; Thanks to Tom Joyce for creating a prototype
; from which this program was derived.

__UNICODE__ equ 1           ; UNICODE build

    .686p                       ; create 32 bit code
    .mmx                        ; enable MMX instructions
    .xmm                        ; enable SSE instructions
    .model flat, stdcall        ; 32 bit memory model
    option casemap :none        ; case sensitive
INCLUDE main.inc







;=================== CODE =========================
.code
WinMain PROC


; Get a handle to the current process.
INVOKE GetModuleHandle, NULL
mov hInstance, eax



; Create the application's main window.
; Returns a handle to the main window in EAX.
call createTheWindow

WinMain ENDP

createTheWindow PROC
LOCAL Wwd:DWORD,Wht:DWORD,Wtx:DWORD,Wty:DWORD,mWid:DWORD
    LOCAL wc:WNDCLASSEX

    STRING szClassName,   "Custom_Button_Class"
    STRING szDisplayName, "Custom Bitmap Buttons"

    invoke InitCommonControls

  ; ---------------------------------------------------
  ; set window class attributes in WNDCLASSEX structure
  ; ---------------------------------------------------
    mov wc.cbSize,         sizeof WNDCLASSEX
    mov wc.style,          CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
    m2m wc.lpfnWndProc,    OFFSET WndProc
    mov wc.cbClsExtra,     NULL
    mov wc.cbWndExtra,     NULL
    m2m wc.hInstance,      hInstance
    m2m wc.hbrBackground,  COLOR_BTNFACE+1
    mov wc.lpszMenuName,   NULL
    mov wc.lpszClassName,  OFFSET szClassName
    m2m wc.hIcon,          hIcon
    m2m wc.hCursor,        hCursor
    m2m wc.hIconSm,        hIcon

  ; ------------------------------------
  ; register class with these attributes
  ; ------------------------------------
    invoke RegisterClassEx, ADDR wc

    mov Wwd, 400
    mov Wht, 425

  ; ------------------------------------------------
  ; Top X and Y co-ordinates for the centered window
  ; ------------------------------------------------
    mov eax, sWid
    sub eax, Wwd                ; sub window width from screen width
    shr eax, 1                  ; divide it by 2
    mov Wtx, eax                ; copy it to variable

    mov eax, sHgt
    sub eax, Wht                ; sub window height from screen height
    shr eax, 1                  ; divide it by 2
    mov Wty, eax                ; copy it to variable

    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPED,
                          Wtx,Wty,Wwd,Wht,
                          NULL,NULL,
                          hInstance,NULL
    mov hWnd,eax

; ---------------------------------------------------
; calling the custom control for bitmap buttons.
; bitmaps are loaded as resources in the RSRC.RC file
; ---------------------------------------------------
    invoke BmpButton,hWnd,20,20,605,606,500
  ; ---------------------------------------------------

    invoke LoadMenu,hInstance,600
    invoke SetMenu,hWnd,eax

    invoke ShowWindow,hWnd, SW_SHOWNORMAL
    invoke UpdateWindow,hWnd

    call MsgLoop
    ret
createTheWindow endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

MsgLoop proc

    LOCAL msg:MSG

    push ebx
    lea ebx, msg
    jmp getmsg

  msgloop:
    invoke TranslateMessage, ebx
    invoke DispatchMessage,  ebx
  getmsg:
    invoke GetMessage,ebx,0,0,0
    test eax, eax
    jnz msgloop

    pop ebx
    ret

MsgLoop endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

    LOCAL var    :DWORD
    LOCAL caW    :DWORD
    LOCAL caH    :DWORD
    LOCAL fname  :DWORD
    LOCAL opatn  :DWORD
    LOCAL spatn  :DWORD
    LOCAL rct    :RECT
    LOCAL buffer1[260]:TCHAR ; these are two spare buffers
    LOCAL buffer2[260]:TCHAR ; for text manipulation etc..

    Switch uMsg
      Case WM_COMMAND
      ; -------------------------------------------------------------------
        Switch wParam

     

          case 1999
          app_close:
            invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL

        Endsw
      ; -------------------------------------------------------------------

     

      case WM_CREATE

      case WM_SIZE
      case WM_CLOSE
      ; -----------------------------
      ; perform any required cleanups
      ; here before closing.
      ; -----------------------------

      case WM_DESTROY
        invoke PostQuitMessage,NULL
        return 0

    Endsw

    invoke DefWindowProc,hWin,uMsg,wParam,lParam

    ret

WndProc endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

MsgboxI proc hParent:DWORD,pText:DWORD,pTitle:DWORD,mbStyle:DWORD,IconID:DWORD

    LOCAL mbp   :MSGBOXPARAMS

    or mbStyle, MB_USERICON

    mov mbp.cbSize,             SIZEOF mbp
    m2m mbp.hwndOwner,          hParent
    mov mbp.hInstance,          rv(GetModuleHandle,0)
    m2m mbp.lpszText,           pText
    m2m mbp.lpszCaption,        pTitle
    m2m mbp.dwStyle,            mbStyle
    m2m mbp.lpszIcon,           IconID
    mov mbp.dwContextHelpId,    NULL
    mov mbp.lpfnMsgBoxCallback, NULL
    mov mbp.dwLanguageId,       NULL

    invoke MessageBoxIndirect,ADDR mbp

    ret

MsgboxI endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

END WinMain

main.inc

Code: [Select]
;     include files
;     ~~~~~~~~~~~~~
      include \masm32\INCLUDE\windows.inc
      include \masm32\INCLUDE\masm32.inc
      include \masm32\INCLUDE\gdi32.inc
      include \masm32\INCLUDE\user32.inc
      include \masm32\INCLUDE\kernel32.inc
      include \masm32\INCLUDE\Comctl32.inc
      include \masm32\INCLUDE\comdlg32.inc
      include \masm32\INCLUDE\shell32.inc
      include \masm32\INCLUDE\oleaut32.inc
      include \masm32\INCLUDE\msvcrt.inc

      include \masm32\macros\macros.asm

;     libraries
;     ~~~~~~~~~
      includelib \masm32\LIB\masm32.lib
      includelib \masm32\LIB\gdi32.lib
      includelib \masm32\LIB\user32.lib
      includelib \masm32\LIB\kernel32.lib
      includelib \masm32\LIB\Comctl32.lib
      includelib \masm32\LIB\comdlg32.lib
      includelib \masm32\LIB\shell32.lib
      includelib \masm32\LIB\oleaut32.lib
      includelib \masm32\LIB\msvcrt.lib

 ; -----------------
 ; Local prototypes
 ; -----------------
        WndProc          PROTO :DWORD,:DWORD,:DWORD,:DWORD
        MsgLoop          PROTO
        Main             PROTO
        MsgboxI          PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD

; ÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-÷-

  ; -----------------------------
  ; uninitialised data allocation
  ; -----------------------------
    .data?
        hInstance   dd ?
        hWnd        dd ?
        hIcon       dd ?
        hCursor     dd ?
        CommandLine dd ?
        sWid        dd ?
        sHgt        dd ?

So I am trying to create a basic window with a button in it. The problem is,
a. The window does not come up when I run it
b. I don't know how to load bitmap images. Is there a way to do it without resource files in visual studio? I am not sure what to do...


dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #1 on: November 21, 2012, 07:43:06 AM »
the first thing i noticed is that WinMain is missing a call to ExitProcess
but, that shouldn't prevent a window from showing up   :P
if i have some time a little later, i will look at it closer

not sure i would use vs 2010 for straight asm code

welcome to the forum   :t

carre89

  • Guest
Re: [First timer]Window will not show up
« Reply #2 on: November 21, 2012, 08:00:23 AM »
Thankyou for the reply. I just added

"invoke exitprocess, eax"

before WinMain endp

Also I found a procedure that can load a bitmap from a file.

BitmapFromFile proc pszFileName:DWORD

If I have a .bmp file in the project directory, how do I call this function? I tried doing this:
Code: [Select]
.data
      button dd ?
      buttonPath DWORD "button.bmp",0
.code
       invoke BitmapFromFile, addr buttonPath,0
mov button, eax
       invoke BmpButton,hWnd,20,20,button,button,500

Sorry if these are stupid questions. :redface:

jj2007

  • Member
  • *****
  • Posts: 10087
  • Assembler is fun ;-)
    • MasmBasic
Re: [First timer]Window will not show up
« Reply #3 on: November 21, 2012, 08:13:51 AM »
Check your results for calculating window sizes.
Welcome to the Forum :icon14:

1.   call createTheWindow
   exit

2.    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPED,
                          100,100,400,300,
                          NULL,NULL,
                          hInstance,NULL
    mov hWnd,eax


You might shorten it a little bit:
include \masm32\MasmBasic\MasmBasic.inc   ; download
TITLE Windows Application                   (WinApp.asm)

; -----------------

[delete all that header stuff, including the include main.inc - it saves typing]

 ; Local prototypes
 ; -----------------
... and then insert one line to see what's going on:
    mov Wty, eax                ; copy it to variable
   deb 1, "Win", Wwd, Wht, Wtx, Wty

Hint: shr instead of sar is one problem, but not the only one.

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #4 on: November 21, 2012, 08:19:11 AM »
it should be...
Code: [Select]
        invoke  ExitProcess,eaxthe case is not important for "invoke" or "eax", but it is for the function name

EDIT: i see Jochen used the "exit" macro, instead   :P
a little simpler, but does not return the value in EAX - it always returns 0 (a minor point, really)

i haven't used that function from the masm32 library
but - it probably calls LoadImage

http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045%28v=vs.85%29.aspx

the filename string should be declared in the .DATA section
then, you pass the address of that string (a "pointer") to the function

this code should yield an HBITMAP (bitmap handle) in eax
Code: [Select]
        .DATA

szButtonBmp db 'button.bmp',0

        .CODE

        INVOKE  LoadImage,NULL,offset szButtonBmp,IMAGE_BITMAP,NULL,NULL,LR_LOADFROMFILE

notice that the filename string is defined using DB, not DW
if you want a UNICODE string, probably best to use a macro or something

when you are done using the HBITMAP, you should use DeleteObject to release the handle   :t

CommonTater

  • Guest
Re: [First timer]Window will not show up
« Reply #5 on: November 21, 2012, 08:29:50 AM »
Code: [Select]
    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPED | WS_VISIBLE,                       <---- here
                          Wtx,Wty,Wwd,Wht,
                          NULL,NULL,
                          hInstance,NULL
So I am trying to create a basic window with a button in it. The problem is,
a. The window does not come up when I run it

You need to either tell it to be visible with WS_VISIBLE or invoke ShowWindow() to make it pop up on the screen.  Windows are not visible by default...



carre89

  • Guest
Re: [First timer]Window will not show up
« Reply #6 on: November 21, 2012, 08:31:55 AM »
YES! That worked! And I made the modifications to load the bitmap to a button but the button doesn't show up.
Here is a .zip of my project.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7027
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: [First timer]Window will not show up
« Reply #7 on: November 21, 2012, 08:32:15 AM »
 :biggrin:

> Sorry if these are stupid questions.

No need to apologise, if you have seen some of the messes that we have all made, you would laugh too.  :P
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

carre89

  • Guest
Re: [First timer]Window will not show up
« Reply #8 on: November 21, 2012, 09:51:48 AM »
So I cleaned up the code a little bit by removing everything that I am not using. I am going to try to figure out why load .bmp isn't working and try to get a button to showup in the window. I attach my project just in case anyone wants to take a crack at it.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7027
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: [First timer]Window will not show up
« Reply #9 on: November 21, 2012, 10:35:32 AM »
I don't have time today but make a point of checking the return value of LoadBitmap.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #10 on: November 21, 2012, 12:13:07 PM »
you have defined __UNICODE__ = 1
so - when you call LoadImage, it is actually using LoadImageW
that function wants a UNICODE string for the filename

there are a few ways to fix this issue:

1) if there is no reason to create a UNICODE version, don't define __UNICODE__
    all the strings will then be ASCII
2) define the filename string using TCHARS or WORDS, each character individually
Code: [Select]
szButtonBmp TCHAR 'b','u','t','t','o','n','.','b','m','p',03) use a macro to create the UNICODE string - i forget what the name of the macro is   :P
4) create a UNICODE program, but call LoadImageA explicitly and use an ASCII string

carre89

  • Guest
Re: [First timer]Window will not show up
« Reply #11 on: November 22, 2012, 04:10:52 AM »
I would like to take approach #1. I am wasn't taught the differences between character encodings in assembly so I would rather not dabble with that. So I commented out the unicode declaration but now my program is trying to access illegal memory addresses. I have no idea why it's crashing. Here is a copy of the latest revision to my project if anyway wants to take a look at it.

Thank you guys for your help so far.   :t

PS: Is there a way to know if the bmpbutton was right clicked?

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #12 on: November 22, 2012, 04:33:59 AM »
i don't have VC set up - lol
and - even if i did, i am not much of a C programmer   :P

give me a few minutes to make an asm version...

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #13 on: November 22, 2012, 07:45:53 AM »
ok - fixed a few minor things...

used COLOR_BTNFACE+1 as the class background color and IDC_ARROW as the class cursor
used WS_OVERLAPPEDWINDOW for the window style - this gives you the min/max/close buttons in the title bar
swapped the names of "hWin" and "hWnd" - this is what we are used to, is all   :P
also - i initialize hWin in WM_CREATE rather than in the main code - my preference
moved the image load code from the main routine to WM_CREATE
reorganized the program a bit - it was looking pretty sloppy - lol

at this point, i can use LoadImage to create a valid handle for the image from file
for the fun of it, i created a static control to show the loaded image

now - for the real problem...
the BmpButton routine contained in the masm32 package is designed to use 2 images from resource
eventually, you are probably going to want to put these images in resource, rather than access them from files

however, the routine could use a few improvements
it requires an image ID for the "up" and "down" button states - you could probably use the same image for both
more importantly, it does not allow for the use of an image strip
ideally, multiple images are placed in a single resource bitmap, then accessed by an x-coord index
another issue is that the routine always creates buttons that are 100 x 100
then, it creates a static control inside the button for the image
static controls automatically resize themselves to an image - buttons do not   :P

maybe i will make a new routine later on
i have a custom button routine already written - which always uses 16 x 16 images from a strip
it creates buttons with borders and states - very similar to the MFC ones like those used in MS Paint
so - a little modification is all that we'd need to make it size-to-image

but - i am working on a little bug with my buttons - this is my current project, as it happens
i provide for a message to set the button state, type, tool-tip string, etc
if you send that message when handling a button click - things get a little messed up - lol
it seems to be a thread-conflict issue - i'm not sure - so, i am working on that

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: [First timer]Window will not show up
« Reply #14 on: November 22, 2012, 09:07:56 AM »
giving this a little more thought....

if you want to create a grid-type game, like mine sweeper, you probably don't want to use individual buttons
in "advanced" mode, WinMine creates 30 x 16 squares - that would be 480 buttons - lol
that seems like an awful lot of system resources for a simple game
also - windows standard buttons don't send messages to the parent window for right-clicks
they have borders and can also have rounded corners - not what you're after

it would make much more sense to just handle the displayed grid in WM_PAINT
and handle the mouse clicks by calculating the grid location - essentially making one big customized button, if you will
set up an array that holds the state for each grid square