GUI app and winAPI calls
#1
Usual VB method is :
Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA"(ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Long) As Long

but what i found is awkward way with :
FUNCTION CreateWindowExA%& (BYVAL dwExStyle~&, BYVAL lpClassName%&, BYVAL lpWindowName%&, BYVAL dwStyle~&, BYVAL x&, BYVAL y&, BYVAL nWidth&, BYVAL nHeight&, BYVAL hWndParent%&, BYVAL hMenu%&, BYVAL hInstance%&, BYVAL lpParam%&)

I will try reconstruct this ...
Reply
#2
Here is the declaration I use and it works great:
Code: (Select All)
Declare CustomType Library
    Function CreateWindowEx%& (ByVal dwExStyle As Unsigned Long, Byval lpClassName As Offset, Byval lpWindowName As Offset, Byval dwStyle As Unsigned Long, Byval x As Long, Byval y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As Offset, Byval hMenu As Offset, Byval hInstance As Offset, Byval lpParam As Offset)
End Declare

You really only need to use the "A" suffix when calling directly from the DLL. If you use the header files instead, Windows will automatically select the "A" version. So you won't need CreateWindowExA in my declaration but you would if you pulled it from the DLL.
Ask me about Windows API and maybe some Linux stuff
Reply
#3
Hi Zak

Thanks ..but that is not only problem , ihave problem with _OFFSET
so my question is why is
Code: (Select All)
Byval lpClassName As Offset, Byval lpWindowName As Offset
why this two arguments are pointers ..or better string pointers?

and also why is parent handler pointer ?
Code: (Select All)
Byval hWndParent As Offset
ok first two i can understand but why window handler which is integer or long ?
Reply
#4
things go more weird when compiler exit with syntax error about parens (

and code is this :

Code: (Select All)
FUNCTION CreateWindowEx%& (ByVal dwExStyle As Long, Byref lpClassName As String, Byref lpWindowName As String, Byval dwStyle As Long, Byval x As Long, Byval y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As Long, Byval hMenu As Long, Byval hInstance As Long, Byval lpParam As Long )
Reply
#5
and more Zak

you use Offset without  _OFFSET ...so what i s proper ?
Reply
#6
I really don't get it what is problem with _OFFSET
or probably i am doing something wrong
here is code:

Code: (Select All)
'test 1 GUI win32 api in QB64pe v3.2.1 by Aurel

CONST IDC_ARROW = &H7F00
    CONST COLOR_WINDOW = 5
     
    CONST WS_OVERLAPPED = 0
    CONST WS_CHILD = &H40000000
    CONST WS_VISIBLE = &H10000000
    CONST WS_MAXIMIZE = &H01000000
    CONST WS_CAPTION = &H00C00000
    CONST WS_VSCROLL = &H00200000
    CONST WS_HSCROLL = &H00100000
    CONST WS_SYSMENU = &H00080000
    CONST WS_THICKFRAME = &H00040000
    CONST WS_TABSTOP = &H00010000
    CONST WS_MINIMIZEBOX = &H00020000
    CONST WS_MAXIMIZEBOX = &H00010000
    CONST WS_OVERLAPPEDWINDOW = WS_OVERLAPPED OR WS_CAPTION OR WS_SYSMENU OR WS_THICKFRAME OR WS_MINIMIZEBOX OR WS_MAXIMIZEBOX
     
    CONST CW_USEDEFAULT = &H80000000
     
    CONST BS_PUSHBUTTON = 0
    CONST BS_AUTOCHECKBOX = 3
    CONST BS_GROUPBOX = 7
    CONST BS_AUTORADIOBUTTON = 9
    CONST BS_TEXT = 0
     
    CONST BN_CLICKED = 0
     
    CONST BM_GETCHECK = &HF0
     
    CONST ES_LEFT = 0
    CONST ES_MULTILINE = 4
    CONST ES_AUTOVSCROLL = &H0040
    CONST ES_AUTOHSCROLL = &H0080
    CONST ES_WANTRETURN = &H1000
     
    CONST WM_DESTROY = 2
    CONST WM_GETTEXT = &H000D
    CONST WM_CLOSE = &H0010
    CONST WM_COMMAND = &H0111
     
    CONST SW_SHOWDEFAULT = &HA
    CONST SW_SHOW        = 5
     
    DECLARE LIBRARY "win"
        FUNCTION GetWindowProc%& ()
    END DECLARE
     
DECLARE DYNAMIC LIBRARY "user32"
        FUNCTION SendMessageA%& (BYVAL hWnd%&, BYVAL Msg~&, BYVAL wParam~%&, BYVAL lParam%&)
        FUNCTION DefWindowProcA%& (BYVAL hWnd%&, BYVAL Msg~&, BYVAL wParam~%&, BYVAL lParam%&)
        SUB PostQuitMessage (BYVAL nExitCode&)
        FUNCTION LoadCursorW%& (BYVAL hInstance%&, BYVAL lpCursorName%&)
        FUNCTION RegisterClassA~% (BYVAL lpWndClass%&)

FUNCTION CreateWindowEx%& (ByVal dwExStyle As Long, byval lpClassName As _OFFSET,byval  lpWindowName As _OFFSET, Byval dwStyle As Long, Byval x As Long, Byval y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As Long, Byval hMenu As Long, Byval hInstance As Long, Byval lpParam As Long )

        FUNCTION ShowWindow& (BYVAL hWnd%&, BYVAL nCmdShow&)
        FUNCTION UpdateWindow& (BYVAL hWnd%&)
        FUNCTION GetMessageA& (BYVAL lpMsg%&, BYVAL hWnd%&, BYVAL wMsgFilterMin~&, BYVAL wMsgFilterMax~&)
        FUNCTION TranslateMessage& (BYVAL lpMsg%&)
        FUNCTION DispatchMessageA%& (BYVAL lpmsg%&)
END DECLARE
     
    DECLARE DYNAMIC LIBRARY "kernel32"
        FUNCTION GetModuleHandleW%& (BYVAL lpModuleName%&)
        'FUNCTION GetLastError~& ()
    END DECLARE

   TYPE POINT
        x AS LONG
        y AS LONG
    END TYPE

' $IF 32BIT THEN
        TYPE MSG
            hwnd AS LONG
            message AS LONG
            wParam AS LONG 'unsigned pointer sized integer
            lParam AS _OFFSET 'pointer sized integer
            time AS LONG
            pt AS POINT
        END TYPE
     
        TYPE WNDCLASSA
            style AS LONG
            lpfnWndProc AS _OFFSET
            cbClsExtra AS LONG
            cbWndExtra AS LONG
            hInstance AS _OFFSET
            hIcon AS _OFFSET
            hCursor AS _OFFSET
            hbrBackground AS _OFFSET
            lpszMenuName AS _OFFSET
            lpszClassName AS _OFFSET
        END TYPE
   

    DIM SHARED hi AS _OFFSET
    DIM SHARED bRet AS LONG
    DIM SHARED hw AS LONG
    DIM SHARED hwb0 AS _OFFSET
    DIM SHARED hwb1 AS _OFFSET
    DIM SHARED hwcb AS _OFFSET
    DIM SHARED hwgb AS _OFFSET
    DIM SHARED hwr0 AS _OFFSET
    DIM SHARED hwr1 AS _OFFSET
    DIM SHARED hwe AS _OFFSET
    DIM SHARED wc AS WNDCLASSA
    DIM SHARED wmsg AS MSG
    DIM SHARED at AS _UNSIGNED INTEGER
     
    DIM SHARED buf AS STRING * 4096
     
    'DIM SHARED discardb AS LONG
    'DIM SHARED discardp AS _OFFSET
    DIM SHARED t0 AS STRING
    DIM SHARED t1 AS STRING
     
    DIM SHARED ClassName AS STRING
    ClassName = "QB64pe" + CHR$(0)
    'DIM SHARED crlf AS STRING * 2
    'crlf = MKI$(&HA0D)
     
    hi = GetModuleHandleW(0)
     
    wc.style = 0
    wc.lpfnWndProc = GetWindowProc
    wc.cbClsExtra = 0
    wc.cbWndExtra = 0
    wc.hInstance = hi
    wc.hIcon = 0
    wc.hCursor = LoadCursorW(0, IDC_ARROW)
    wc.hbrBackground = COLOR_WINDOW + 1
    wc.lpszMenuName = 0
    wc.lpszClassName = _OFFSET(ClassName)
     
    at = RegisterClassA(_OFFSET(wc)): IF 0 = at THEN SYSTEM

'create main window
t1 = "title" + CHR$(0)
hw = CreateWindowEx(0, _OFFSET(ClassName) , _OFFSET(t1), WS_OVERLAPPEDWINDOW , 200, 200, 800, 600, 0, 0, hi, 0)
IF 0 = hw THEN SYSTEM

ShowWindow(hw, SW_SHOW)
UpdateWindow(hw)

'win message loop

  While GetMessageA(_OFFSET(wmsg), 0, 0, 0) <> 0
          TranslateMessage(_OFFSET(wmsg))
           DispatchMessageA(_OFFSET(wmsg))
       Wend   


Attached Files Image(s)
   
Reply
#7
It looks like this is because you defined "hw" as LONG but CreateWindowEx returns an OFFSET. Make sure all your handles are OFFSETs.

As for the underscore vs not.... I usually code with $NOPREFIX turned on and I just copied and pasted from code I had opened. Oops. Also, your declaration for CreateWindowEx has some variable type mismatches. Copy the declaration I gave you (but fix the underscores) and also replace DECLARE DYNAMIC LIBRARY "user32" in your code with DECLARE CUSTOMTYPE LIBRARY. Otherwise, you're going to need the "A" at the end of CreateWindowEx. If you don't change either the library declaration or the name of the function, then you will hit a runtime error saying that function doesn't exist in the library.
Ask me about Windows API and maybe some Linux stuff
Reply
#8
Quote:Make sure all your handles are OFFSETs.

all handles must be _OFFSET ..why ..in other windows compilers there are INTEGER or LONG
why is in QB64 pointer?

and also when i try to copy code
original author made  this  as className ..what is that

hw = CreateWindowEx(0, at AND &HFFFF~&, _OFFSET(t1), WS_OVERLAPPEDWINDOW , 200, 200, 800, 600, 0, 0, hi, 0)
Reply
#9
(03-22-2023, 08:13 PM)aurel Wrote: all handles must be _OFFSET ..why ..in other windows compilers there are INTEGER or LONG
why is in QB64 pointer?

It was a half-successful attempt to ease the life of the programmer moving from 32-bit to 64-bit. A pointer isn't supposed to be dictated by what's its size. Remember that _OFFSET and _MEM are necessary in QB64(PE) because otherwise it would have to look like Freebasic or Purebasic which, in turn, look the most like C and C++.

I guess in this case use ConvertOffset&&() function that Steve wrote and is in QB64 Wiki. But that returns _INTEGER64 and not INTEGER or LONG. INTEGER is always 16-bit integer in QuickBASIC and descendants, shouldn't be discussed any longer in systems programming.
Reply
#10
A HANDLE is a long pointer. In QB64, our equivalent is an OFFSET. A long pointer is 4 bytes in 32 bit and 8 in 64. In QB64, an OFFSET is 4 bytes in 32 bit and 8 in 64. It's our closest approximation. As for the class name with the "at AND &HFFFF~&", I'm not sure where they would have gotten that value for their class. Very odd. I've not seen something like that before. If I were you, I'd instead use the actual name of the class and keep the declaration with OFFSET. It looks like you defined it as "QB64pe". So just pass it as _OFFSET(ClassName) in your call there rather than that weird "at AND &HFFFF~&".
Ask me about Windows API and maybe some Linux stuff
Reply




Users browsing this thread: 12 Guest(s)