PowerBASIC Peer Support Forums
 

Go Back   PowerBASIC Peer Support Forums > User to user Discussions > PowerBASIC Inline Assembler

PowerBASIC Inline Assembler User to user discussions concerning use of Inline Assembler in PowerBASIC programs. Questions, answers, and sample code are all welcomed.

Reply
 
Thread Tools Display Modes
  #1  
Old Mar 30th, 2012, 06:31 PM
Chris Holbrook Chris Holbrook is offline
Member
 
Join Date: Aug 2005
Location: in Hiding
Posts: 6,528
Wndproc in assembler

Please could someone point me at a wndproc written in assembler? It doesn't have to do anything, I just want to see how to handle the parameters, clean up the stack, return.
Reply With Quote
  #2  
Old Mar 30th, 2012, 07:35 PM
Chris Holbrook Chris Holbrook is offline
Member
 
Join Date: Aug 2005
Location: in Hiding
Posts: 6,528
OK found one, just being lazy...
Code:
zzz proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
mov eax,[wmsg]
cmp eax,2 ;WM_DESTROY
je wmdestroy
defwndproc:
push [lparam]
push [wparam]
push [wmsg]
push [hwnd]
call DefWindowProcA
jmp finish
 
wmdestroy:
push 0
call PostQuitMessage ;Quit
xor eax,eax
 
finish: 
ret
 
zzz endp
Reply With Quote
  #3  
Old Apr 3rd, 2012, 07:53 AM
Steve Hutchesson Steve Hutchesson is online now
Member
 
Join Date: Oct 1999
Location: Sydney Australia
Posts: 2,450
Chris,

Here is one that works in late versions of PBWIN 10. The code you posted looks like an old Turbo Assembler WndProc.

It can be done but there are no great gains in doing so and you have to get the addresses of the APIs yourself using LoadLibrary/GetProcAddress.

Code:
' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

    #include "\basic\include\win32api.inc"

    MACRO entry_point = PBmain

    GLOBAL hInstance as DWORD
    GLOBAL hIcon     as DWORD
    GLOBAL hWnd      as DWORD

    GLOBAL hUser            as DWORD
    GLOBAL pPostQuitMessage as DWORD
    GLOBAL pDefWindowProcA  as DWORD

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FUNCTION entry_point as LONG

    LOCAL Wid          as LONG
    LOCAL Hgt          as LONG
    LOCAL wcex         as WNDCLASSEX
    LOCAL szClassName  as ASCIIZ * 32
    LOCAL Sw as DWORD
    LOCAL Sh as DWORD

    hInstance = GetModuleHandle(ByVal %NULL)                ' application instance handle
    hIcon     = LoadIcon(hInstance,ByVal 2)                 ' application icon handle
    Sw        = GetSystemMetrics(%SM_CXSCREEN)              ' screen width
    Sh        = GetSystemMetrics(%SM_CYSCREEN)              ' screen height

    GetAddresses

    DisplayName$ = "PB Asm WndProc"
    szClassName  = "Application_Class"

  ' ----------------------------------------------------------------------
  ' set the arguments to determine the characteristics of the window class
  ' ----------------------------------------------------------------------
    wcex.cbSize        = SIZEOF(wcex)
    wcex.style         = %CS_BYTEALIGNCLIENT or %CS_BYTEALIGNWINDOW
    wcex.lpfnWndProc   = CODEPTR(WndProc)
    wcex.cbClsExtra    = 0
    wcex.cbWndExtra    = 0
    wcex.hInstance     = hInstance
    wcex.hIcon         = hIcon
    wcex.hCursor       = LoadCursor(%NULL,ByVal %IDC_ARROW)
    wcex.hbrBackground = %COLOR_BTNFACE + 1
    wcex.lpszMenuName  = %NULL
    wcex.lpszClassName = VarPtr(szClassName)
    wcex.hIconSm       = hIcon

  ' ---------------------------------------------
  ' register the class with those characteristics
  ' ---------------------------------------------
    RegisterClassEx wcex

  ' -----------------------------------------------
  ' Set Width & Height to percentage of screen size
  ' -----------------------------------------------
    Wid = Sw * .70
    Hgt = Sh * .70

  ' ---------------------------------------
  ' limit the aspect ratio for wide screens
  ' ---------------------------------------
    If Wid > Hgt * 1.4 Then
      Wid = Hgt * 1.4
    End If

  ' ------------------------
  ' Window is self centering
  ' ------------------------
    hWnd = CreateWindowEx( _
           %WS_EX_LEFT, _                  ' extended style
           szClassName, _                  ' window class name
           ByVal StrPtr(DisplayName$), _   ' window title
           %WS_OVERLAPPEDWINDOW, _         ' window style
           Sw\2-(Wid\2), _                 ' initial x position
           Sh\2-(Hgt\2), _                 ' initial y position
           Wid, _                          ' initial x size
           Hgt, _                          ' initial y size
           %NULL, _                        ' parent window handle
           %NULL, _                        ' window menu handle
           hInstance, _                    ' program instance handle
           ByVal %NULL)                    ' creation parameters

   '-------------------------

    ShowWindow hWnd, %SW_SHOW
    UpdateWindow hWnd

    MessageLoop

    FreeLibrary hUser

    FUNCTION = 0

END FUNCTION

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FUNCTION MessageLoop() as DWORD

    LOCAL pst as DWORD                                      ' DWORD pointer for structure
    LOCAL msg as tagMSG                                     ' message structure

    pst = VarPtr(msg)                                       ' get pointer address
    ! jmp nxt_msg                                           ' jump into MsgLoop

  MsgLoop:
    TranslateMessage ByVal pst
    DispatchMessage  ByVal pst
  nxt_msg:
    GetMessage ByVal pst,0,0,0
    ! test eax, eax
    ! jne MsgLoop

    FUNCTION = msg.wParam

END FUNCTION

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FASTPROC WndProc

    PREFIX "!"

    push ebp                                  ; set up a stack frame
    mov ebp, esp

    cmp DWORD PTR [ebp+12], 2                 ; WM_DESTROY
    jne lbl0
    push 0
    call pPostQuitMessage
    lbl0:

    push DWORD PTR [ebp+20]
    push DWORD PTR [ebp+16]
    push DWORD PTR [ebp+12]
    push DWORD PTR [ebp+8]
    call pDefWindowProcA

    leave                                     ; exit the stack frame
    ret 16                                    ; balance stack on exit

    END PREFIX

END FASTPROC

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

SUB GetAddresses()

    hUser = LoadLibrary("user32.dll")

    pPostQuitMessage = GetProcAddress(hUser,"PostQuitMessage")
    pDefWindowProcA  = GetProcAddress(hUser,"DefWindowProcA")

END SUB

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
__________________
hutch at movsd dot com
www.masm32.com
Reply With Quote
  #4  
Old Apr 3rd, 2012, 02:54 PM
Chris Holbrook Chris Holbrook is offline
Member
 
Join Date: Aug 2005
Location: in Hiding
Posts: 6,528
Thanks Hutch.

Meanwhile I came up with this:
Code:
....
local retaddr as long

' entry point
cbproc1: 
        ' called here with hWnd, umsg, wparam and lparam
        !pop retaddr
        !pop hwnd
        !pop umsg
        !pop wparam
        !pop lparam
' test message type here, etc
        !mov eax, &H55 ' arbitrary return value for testing
        !push retaddr
        !ret
It appeared to balance the stack and get back to the right place. It is a way of embedding a Wndproc in a METHOD.


Just messing around - don't try this at home folks!
Reply With Quote
Reply

Tags
assembler, callback, wndproc

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:57 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright 1999-2011 PowerBASIC, Inc. All Rights Reserved.
Error in my_thread_global_end(): 1 threads didn't exit