home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PCACHSRC.ZIP / WINHULLO.ASM < prev    next >
Assembly Source File  |  1991-08-20  |  13KB  |  394 lines

  1. ;WINHULLO.ASM --> WINHULLO.EXE  Windows demo program.
  2.  
  3. ;****NOTE**** these WINHULLO files may not be exactly the same as
  4. ;those listed in the textbook.  The book listings were developed for
  5. ;Microsoft C version 6.00 and the SDK.  The files have since been
  6. ;modified to work with Borland C++ version 2.0.  Look at the code
  7. ;below and you will see where I have commented-out some code and
  8. ;replaced it with more efficient code that TASM can understand.
  9. ;You can convert back if necessary.
  10.  
  11. .MODEL SMALL    ;, WINDOWS PASCAL
  12.  
  13. ;the following equates could have been placed in a separate
  14. ;include file.... (note that I got these from WINDOWS.H which is
  15. ;part of the Microsoft SDK)
  16. IDI_APPLICATION EQU    32512    ;identifier for icon type.
  17. IDC_ARROW        EQU    32512    ;identifier for cursor type.
  18. OEM_FIXED_FONT    EQU    10        ;identifier for font type.
  19. COLOR_BACKGROUND EQU 1        ;identifier for background colour.
  20.  
  21. WM_CREATE        EQU    1        ;these are messages from Windows.
  22. WM_DESTROY    EQU    2        ;    /
  23. WM_PAINT        EQU    15        ;    /
  24. WM_COMMAND    EQU    273        ;    /
  25. WM_LBUTTONDOWN    EQU    513        ;    /
  26. WM_CHAR        EQU    258        ;    /
  27.  
  28. IDM_QUIT        EQU    100        ;menu-identifiers from Windows -- must
  29. IDM_ABOUT        EQU    101        ;be same as defined in .RC file.
  30.  
  31. MB_OK        EQU    0        ;a messagebox type.
  32.  
  33. ;......
  34.  
  35. EXTRN    __acrtused:ABS
  36. EXTRN    UPDATEWINDOW:FAR    ;these are Windows functions.
  37. EXTRN    BEGINPAINT:FAR
  38. EXTRN    ENDPAINT:FAR
  39. EXTRN    DEFWINDOWPROC:FAR
  40. EXTRN    POSTQUITMESSAGE:FAR
  41. EXTRN    REGISTERCLASS:FAR
  42. EXTRN    GETSTOCKOBJECT:FAR
  43. EXTRN    CREATEWINDOW:FAR
  44. EXTRN    SHOWWINDOW:FAR
  45. EXTRN    GETMESSAGE:FAR
  46. EXTRN    LOADCURSOR:FAR
  47. EXTRN    TRANSLATEMESSAGE:FAR
  48. EXTRN    DISPATCHMESSAGE:FAR
  49. EXTRN    LOADICON:FAR
  50. EXTRN    TEXTOUT:FAR
  51. EXTRN    INVALIDATERECT:FAR
  52. EXTRN    MESSAGEBOX:FAR
  53. EXTRN    GETDC:FAR
  54. EXTRN    RELEASEDC:FAR
  55. EXTRN    SELECTOBJECT:FAR
  56.  
  57. .DATA
  58. wintitle    DB    'HULLO DEMO PROGRAM',0
  59. winhulloname    DB    'WINHULLO',0
  60. hOemFont    DW    0            ;handle to OEM font.
  61. _hInst    DW    0
  62. outstring     DB    'Hullo World'
  63. aboutstr    DB    'Assembly Language Windows Demo',0    ;messagebox
  64. titlestr    DB    'Karda Prints',0                ;    /
  65.  
  66. .CODE
  67.  
  68. ;    PUBLIC     WinMain
  69. ;WinMain    PROC    WINDOWS PASCAL NEAR nCmdShow:WORD,lpCmdLine:DWORD,hPrevInstance:WORD,hInstance:WORD
  70. ;****NOTE**** the above two lines are an enhancement available with TASM,
  71. ;providing high-level stack handling at procedure entry and exit... leave the lines
  72. ;commented-out, as this feature is not implemented fully in this file.
  73.  
  74.     PUBLIC    WINMAIN
  75. WINMAIN    PROC NEAR            ;entry point from Windows.
  76. ;                        ;stack will contain return-addr (only 2
  77. ;                        ;bytes), nCmdShow (2), lpCmdLine (4),
  78. ;                        ;hPrevInstance (2), hInstance (2 bytes).
  79. ;                        ;(ret-addr is at top of stack).
  80.     push    bp                ;save BP so can use to access params.
  81.     mov    bp,sp            ;BP will now point to top-of-stack.
  82.     sub    sp,46            ;mov stack to free region.
  83.     cmp    WORD PTR [bp+10],0    ;hPrevInstance. (=0 if no previous inst).
  84.     jne    createwin
  85.  
  86.  
  87.  
  88. ;we only come this way if this is the first instance of the application.
  89. ;The first instance needs to create certain resources, and all following
  90. ;instances can use them....
  91. ;(for this Workshop, skip ahead to "createwin:")
  92. ;The code below is creating a window-class data-structure, as required
  93. ;by RegisterClass() further down....
  94.     mov    WORD PTR [bp-46],3                    ;wndclass
  95.     mov    WORD PTR [bp-44],OFFSET WinHulloProc    ;addr of callback
  96.     mov    WORD PTR [bp-42],SEG WinHulloProc        ;function for window.
  97.     sub    ax,ax
  98.     mov    WORD PTR [bp-40],ax
  99.     mov    WORD PTR [bp-38],ax
  100.     mov    ax,WORD PTR [bp+12]    ;hInstance
  101.     mov    WORD PTR [bp-36],ax
  102.     sub    ax,ax                    ;null -- use Windows default icons.
  103.     push    ax                        ;    /
  104.     mov    cx,IDI_APPLICATION            ;Default application icon.
  105.     sub    dx,dx                    ;    /
  106.     push    dx                        ;    /
  107.     push    cx                        ;    /
  108.     call    FAR PTR LOADICON
  109.     mov    WORD PTR [bp-34],ax
  110.     sub    ax,ax                    ;null -- use Windows default cursor.
  111.     push    ax                        ;    /
  112.     mov    ax,IDC_ARROW                ;Standard arrow cursor.
  113.     cwd                            ;    /
  114.     push    dx                        ;    /
  115.     push    ax                        ;    /
  116.     call    FAR PTR LOADCURSOR
  117.     mov    WORD PTR [bp-32],ax
  118. ;    mov    ax,WHITE_BRUSH        
  119. ;    push    ax
  120. ;    call    FAR PTR GETSTOCKOBJECT
  121.  mov ax,COLOR_BACKGROUND
  122.     mov    WORD PTR [bp-30],ax
  123.     mov    ax,OFFSET DGROUP:winhulloname
  124.     mov    WORD PTR [bp-28],ax
  125.     mov    WORD PTR [bp-26],ds
  126.     mov    WORD PTR [bp-24],ax
  127.     mov    WORD PTR [bp-22],ds
  128.     lea    ax,WORD PTR [bp-46]            ;wndclass
  129.     push    ss                        ;this is address of above data
  130.     push    ax                        ;structure.
  131.     call    FAR PTR REGISTERCLASS        ;registers this class of window.
  132.     or    ax,ax                    ;
  133.     je    quitwinmain
  134.  
  135. createwin:
  136. ;CreateWindow() requires the following params on the stack --
  137. ;long pointer to window class name, lp to window title, type of window,
  138. ;x coord, y coord, width, height, parent-handle, menu-handle, instance-
  139. ;handle, lp to params to pass-on.
  140.     mov    ax,OFFSET DGROUP:winhulloname    ;see _DATA segment.
  141.     push    ds                        ;long-pointer (far address) of
  142.     push    ax                        ;class-name.
  143.     mov    ax,OFFSET DGROUP:wintitle    ;see _DATA segment.
  144.     push    ds                        ;far address of window-title.
  145.     push    ax                        ;    /
  146.     sub    ax,ax                    ;type of window (32-bit value).
  147.     mov    dx,207                    ;    /
  148.     push    dx                        ;    /
  149.     push    ax                        ;    /
  150.     mov    ax,150                    ;x-coord (16-bit).
  151.     push    ax                        ;    /
  152.     sub    ax,ax                    ;y-coord (16-bit).
  153.     push    ax                        ;    /
  154.     mov    ax,400                    ;width (16-bit).
  155.     push    ax                        ;    /
  156.     mov    ax,300                    ;height (16-bit).
  157.     push    ax                        ;    /
  158.     sub    ax,ax
  159.     push    ax                        ;0=no parent for this window.
  160.     push    ax                        ;0=use the class menu.
  161.     mov    ax,WORD PTR [bp+12]            ;hInstance -- handle for this
  162.     mov    WORD PTR _hInst,ax            ;application's instance.
  163.     push    ax                        ;(passed to applic from Windows).
  164.     sub    ax,ax
  165.     push    ax                        ;0=no params to pass-on.
  166.     push    ax                        ;(32-bit long-pointer).
  167.     call    FAR PTR CREATEWINDOW
  168.     mov    WORD PTR [bp-2],ax            ;returns hWnd in AX
  169.                                 ;(handle to the window).
  170.                                 ;Here we save it temporarily.
  171.  
  172.     push ax                        ;ShowWindow() requires hWnd and
  173.     push    WORD PTR [bp+4]    ;nCmdShow    ;nCmdShow on the stack.
  174.     call    FAR PTR SHOWWINDOW            ;Tells Windows to display window.
  175.  
  176.     push    WORD PTR [bp-2]            ;hWnd
  177.     call    FAR PTR UPDATEWINDOW        ;tells Windows to redraw now.
  178.     jmp    SHORT messageloop            ;go to the main message-loop.
  179.  
  180.  
  181. ;This is the main message loop, in which Windows waits for messages
  182. ;by calling GetMessage(), then translates keypresses with
  183. ;TranslateMessage() then passes them back to Windows with
  184. ;DispatchMessage()....
  185. mainloop:
  186.     lea    ax,WORD PTR [bp-20]            ;far-addr of message.
  187.     push    ss                        ;    /
  188.     push    ax                        ;    /
  189.     call    FAR PTR TRANSLATEMESSAGE
  190.  
  191.     lea    ax,WORD PTR [bp-20]            ;far-addr of message.
  192.     push    ss                        ;    /
  193.     push    ax                        ;    /
  194.     call    FAR PTR DISPATCHMESSAGE
  195.  
  196. messageloop:
  197.     lea    ax,WORD PTR [bp-20]            ;long-pointer (far addr) of
  198.     push    ss                        ;message. (we use the stack
  199.     push    ax                        ;region for convenience).
  200.     sub    ax,ax
  201.     push    ax                        ;null
  202.     push    ax                        ;null
  203.     push    ax                        ;null
  204.     call    FAR PTR GETMESSAGE
  205.     or    ax,ax
  206.     jne    mainloop
  207.  
  208. ;GetMessage() returns FALSE (AX=0) if a "quit" message...
  209. ;so here we are quiting....
  210.     mov    ax,WORD PTR [bp-16]    ;return wParam to Windows.
  211. quitwinmain:
  212.     mov    sp,bp
  213.     pop    bp
  214.     ret    10                ;Causes RET to add 10 to SP prior to
  215.                         ;popping ret-address, effectively dumping
  216.                         ;all params (as for PASCAL convention).
  217. WINMAIN    ENDP
  218.  
  219. ;.....................................................................
  220. ;What follows is the "callback" function, that Windows calls after the
  221. ;message has been given back to it via DispatchMessage().
  222. ;This function employs CASE logic to direct execution to specific
  223. ;routines to handle each message.  In many cases the message
  224. ;cannot be handled by the application, so it is sent back to
  225. ;Windows (again!) for default handling....
  226.  
  227.     PUBLIC    WinHulloProc
  228. WinHulloProc    PROC FAR
  229. ;The function is entered with far-return-addr (4 bytes), lParam (4),
  230. ;wParam (2), message-type (2), and window-handle (2 bytes) on the stack
  231. ;(ret-addr on top).
  232.  
  233.     push    ds                ;This is some standard preliminary
  234.     pop    ax                ;shuffling of the registers.
  235.     nop                    ;    /
  236.     inc    bp                ;    / (it is called the prolog code)
  237.     push    bp                ;    /
  238.     mov    bp,sp            ;    /
  239.     push    ds                ;    /
  240.     mov    ds,ax            ;    /
  241.     ASSUME DS: NOTHING        ;    / (enters function with DS=_DATA)
  242.  
  243.     sub    sp,146            ;move the stack to a free region
  244.                         ;(so as not to mess-up the params).
  245.     mov    ax,WORD PTR [bp+12]    ;get message-type.
  246.  
  247.     cmp    ax,WM_CREATE        ;message received after CreateWindow()
  248.     je    xcreate            ;function is called.
  249.     cmp    ax,WM_DESTROY        ;message received if a window is closed.
  250.     je    xquitmessage
  251.     cmp    ax,WM_PAINT        ;message received if Windows has (already)
  252.                         ;redrawn any part of the window (due to
  253.                         ;a size-change for example).
  254.     je    xpaint
  255.     cmp    ax,WM_COMMAND        ;any selection of the menu will produce
  256.     jne    notwmcommand
  257.     jmp    xmenu            ;this message.
  258. notwmcommand:
  259.     cmp    ax,WM_LBUTTONDOWN    ;one of many mouse messages.
  260.     jne    notwmlbutton
  261.     jmp    xbreak
  262. notwmlbutton:
  263.     cmp    ax,WM_CHAR        ;message that a key pressed.
  264.     je    xchar
  265.  
  266. ;Default handling of messages....
  267.     push    WORD PTR [bp+14]    ;hWnd
  268.     push    WORD PTR [bp+12]    ;Message-type
  269.     push    WORD PTR [bp+10]    ;wParam
  270.     push    WORD PTR [bp+8]    ;hi-half of lParam
  271.     push    WORD PTR [bp+6]    ;low-half of lParam
  272.     call    FAR PTR DEFWINDOWPROC
  273.     jmp    xreturn            ;Back to Windows, which will in turn
  274.                         ;return to after DispatchMessage().
  275. ;.................................
  276. xcreate:
  277.     mov     ax,OEM_FIXED_FONT
  278.     push    ax
  279.     call    FAR PTR GETSTOCKOBJECT
  280.     mov    hOemFont,ax        ;handle to font.
  281.     jmp    xbreak
  282.  
  283. xquitmessage:
  284.     sub    ax,ax
  285.     push    ax
  286.     call    FAR PTR POSTQUITMESSAGE
  287.     jmp    xbreak
  288.  
  289. xchar:
  290. ;If I wanted this program to display "Hullo World" only when any key is
  291. ;pressed, TextOut() would have been placed here.
  292. ;note below that BeginPaint() returned a "display context", a handle 
  293. ;required for drawing, but we don't normally use BeginPaint() outside
  294. ;of WM_PAINT cases -- instead we use GetDC()....
  295. ;here is what the code would look like if placed here (in C)....
  296. ;    hDC = GetDC(hWnd);
  297. ;    TextOut(hDC,10,20,"Hullo World",11);
  298. ;    ReleaseDC(hWnd,hDC);
  299. ;If we want the string to be redrawn everytime the window is redrawn,
  300. ;it is better to put TextOut() within the WM_PAINT case... this will
  301. ;also mean that "Hullo World" will appear when the window is first drawn.
  302.     jmp     xbreak
  303.  
  304. xpaint:
  305.     push    WORD PTR [bp+14]    ;hWnd -- handle of current window.
  306.     lea    ax,WORD PTR [bp-42]    ;ps -- far-addr of paint-structure.
  307.     push    ss                ;(BeginPaint() will fill the structure).
  308.     push    ax                ;    /
  309.     call    FAR PTR BEGINPAINT        ;BeginPaint() returns handle hDC.
  310.     mov    WORD PTR [bp-146],ax    ;hDC -- display-context, required
  311.                             ;before can output to screen.
  312.  
  313. ;For this simple demo, any redraw of the Window will cause output of our
  314. ;"hullo world" string....
  315.         ;Windows by default uses the System font, but I
  316.         ;am changing it. I need to attach the new font to the
  317.         ;display....
  318. ;        push    ax                ;hDC
  319. ;        push    hOemFont
  320. ;        call    FAR PTR SELECTOBJECT    ;attaches hOemFont to hDC.
  321.  
  322.  call    SelectObject PASCAL,ax,hOemFont        ;TASM replacement.
  323.  
  324.     push    WORD PTR [bp-146]         ;hDC                    ;hDC
  325.     mov    ax,10                ;16-bit x-coord
  326.     push    ax                    ;    /
  327.     mov    ax,20                ;16-bit y-coord
  328.     push    ax                    ;    /
  329.     mov    ax,offset outstring        ;far-address of string to o/p
  330.     push    ds                    ;    /
  331.     push    ax                    ;    / (note low half pushed 2nd)
  332.     mov    ax,11                ;number of chars in string.
  333.     push    ax
  334.     call    FAR PTR TEXTOUT
  335.  
  336.     push    WORD PTR [bp+14]    ;hWnd
  337.     lea    ax,WORD PTR [bp-42]    ;ps -- far-addr of paint-structure.
  338.     push    ss                ;(filled by BeginPaint()).
  339.     push    ax                ;    /
  340.     call    FAR PTR ENDPAINT
  341.     jmp    SHORT xbreak
  342. ;........................
  343. xmenu:
  344. ;comes here if WM_COMMAND message.  The two parameters associated with
  345. ;the message, lParam & wParam, tell us more....
  346. ;low-order word of lParam=0 if message is a menu-selection.
  347. ;hi-order word of lParam=1 if message is an accelerator-key.
  348. ;If low/lParam<>0, message is from a "control" (such as a scrollbar), and
  349. ;low/lParam=handle of control, hi/lParam=notification code.
  350. ;wParam contains the menu-item, the control-ID or the accelerator-key-ID.
  351.  
  352. ;let's stick with menus... the .RC file assigns the number for each
  353. ;menu-item, and this is what we look for in wParam...
  354.     cmp    WORD PTR [bp+6],0            ;low-half of lParam
  355.     jne    xbreak                    ;test if a menu-message.
  356.     cmp    WORD PTR [bp+10],IDM_QUIT    ;wParam.
  357.     jne    notquit
  358.     jmp    xquitmessage
  359. notquit:
  360.     cmp    WORD PTR [bp+10],IDM_ABOUT
  361.     jne    xbreak                    ;no other menu items.
  362.         ;let's put up a message about this program...
  363. ;        push    WORD PTR [bp+14]    ;hWnd -- handle of parent window.
  364. ;        mov    ax,OFFSET aboutstr    ;far-addr of string to display.
  365. ;        push    ds                ;    /
  366. ;        push    ax                ;    /
  367. ;        mov    ax,OFFSET titlestr    ;far-addr of title of dialog-box.
  368. ;        push    ds                ;    /
  369. ;        push    ax                ;    /
  370. ;        mov    ax,MB_OK            ;type of message-box.
  371. ;        push    ax                ;    / (displays single "ok" button)
  372. ;        call    FAR PTR MESSAGEBOX
  373.  
  374.  call MessageBox PASCAL,WORD PTR [bp+14],SEG aboutstr,OFFSET aboutstr,SEG titlestr,OFFSET titlestr,MB_OK
  375.                     ;TASM replacement***
  376. ;.........................
  377. xbreak:
  378.     sub    ax,ax            ;returns 0 in DX:AX.  (callback functions
  379.     cwd                    ;return a 32-bit (long) value).
  380. xreturn:                    
  381.     dec    bp                ;final standard manipulation of regs.
  382.     dec    bp                ;    /
  383.     mov    sp,bp            ;    / (it is called the epilog code).
  384.     pop    ds                ;    /
  385.     pop    bp                ;    /
  386.     dec    bp                ;    /
  387.     ret    10                ;removes parameters.
  388.  
  389. WinHulloProc    ENDP
  390.  
  391. ;.....................................................................
  392.  
  393.  END
  394.