Oxygen Basic
Programming => Example Code => General => Topic started by: Arnold on October 28, 2018, 02:44:14 AM
-
Hello,
maybe someone can help with this topic. I found this link for a WinGui using Window Class #32770 (a system class for a dialog box).
https://www.freebasic-portal.de/downloads/bibliotheken/wingui-eine-einfache-winapi-gui-bibliothek-358.html
The examples could be done with Oxygenbasic too see e.g. TestDialog1.o2bas:
$ filename="TestDialog1.exe"
'uses rtl32
'uses rtl64
uses corewin
uses console
% Dialog_Box = "#32770" 'System class dialog box - WC_DIALOG (?)
% DS_CENTER=0x0800
INITCOMMONCONTROLSEXt icce
'Load the common controls library...
icce.dwSize = sizeof(INITCOMMONCONTROLSEXt)
icce.dwICC = 0xffff
InitCommonControlsEx(&icce)
char* cmdline
&cmdline=GetCommandLine()
sys hInstance = GetModuleHandle(null)
function CreateNew(string ctlclass, string Caption, sys hParent, id, int x,y,w,h, optional int Style=0, ExtStyle=0, sys lpParam=0) as sys
sys hCtrl
if style=0 then
style=WS_CHILD or WS_VISIBLE or WS_TABSTOP
else
style=WS_VISIBLE or style
end if
hCtrl=CreateWindowEx(ExtStyle, ctlclass, Caption, Style, x,y,w,h, hParent, id, hInstance, lpParam)
if hCtrl=null then mbox "Error: Cannot create " ctlclass
return hCtrl
end function
function Window_Event_Close(sys hWnd, MSG *msg) as uint
'returns 1 when the close button (X) of the window has been clicked.
if msg.hwnd = hWnd and msg.message = 161 then 'WM_NCLBUTTONDOWN 'winuser.h
if msg.wParam = 20 then 'HTCLOSE 'winuser.h
return 1
Else
return 0
end if
end if
end function
Sub WaitEvent(sys hWnd, MSG *msg)
if GetMessage(&msg, 0, 0, 0) <> 0 then
printl msg.message : if msg.message=WM_SIZE then printl "WM_SIZE"
if IsDialogMessage(hWnd, &msg) = 0 then
TranslateMessage(&msg )
DispatchMessage(&msg )
end if
end if
end Sub
'-----------------------------------------------------------------
% id_button=1000
sys MainDlg = CreateNew(Dialog_Box, "Hello World", null, null, 100, 100, 400,400, WS_OVERLAPPEDWINDOW or DS_CENTER) 'DS_CENTER has no effect
sys Button_Ok = CreateNew("Button", "Ok", MainDlg, id_button, 160, 300, 60, 20)
MSG msg
'Event loop:
while 1
WaitEvent(MainDlg, &msg)
if msg.hWnd=MainDlg and msg.message=WM_SYSCOMMAND then
'Alt-F4
if msg.wParam=SC_CLOSE then EndDialog(MainDlg, true) : exit while
end if
select case msg.hwnd
case Button_Ok
If msg.message = WM_LBUTTONDOWN Then
mbox "Ok"
end If
end select
if Window_Event_Close(MainDlg, &msg) then EndDialog(MainDlg, true) : exit while
wend
The problem with this kind of creating a dialog box is the missing dlgproc callback function. Also some messages like WM_COMMAND or WM_SIZE are not recognized. Therefore I tried SetWindowLongPtr to achieve this:
TestDialog2.o2bas:
$ filename "TestDialog2.exe"
'uses rtl32
'uses rtl64
uses corewin
uses console
% Dialog_Box = "#32770" 'System class dialog box - WC_DIALOG (?)
% DS_CENTER=0x0800
% DWL_DLGPROC = sizeof(sys) '4/8
INITCOMMONCONTROLSEXt icce
'Load the common controls library...
icce.dwSize = sizeof(INITCOMMONCONTROLSEXt)
icce.dwICC = 0xffff
InitCommonControlsEx(&icce)
char* cmdline
&cmdline=GetCommandLine()
sys hInstance = GetModuleHandle(null)
function CreateNew(string ctlclass, string Caption, sys hParent, id, int x,y,w,h, optional int Style=0, ExtStyle=0, sys lpParam=0) as sys
sys hCtrl
if style=0 then
style=WS_CHILD or WS_VISIBLE or WS_TABSTOP
else
style=WS_VISIBLE or style
end if
hCtrl=CreateWindowEx(ExtStyle, ctlclass, Caption, Style, x,y,w,h, hParent, id, hInstance, lpParam)
if hCtrl=null then mbox "Error: Cannot create " ctlclass
return hCtrl
end function
function makefont(string Font, optional int h=16, optional w=8, wt=0, it=False, ul=False, so=False) as sys
sys hFont=CreateFont(h, w, 0, 0, wt, it, ul, so,
ANSI_CHARSET, FALSE, FALSE, DEFAULT_QUALITY, DEFAULT_PITCH or FF_ROMAN, Font)
if hFont=null then mbox "Error: Cannot CreateFont hfont"
return hFont
end function
sub setfont(sys hWnd, hFont)
SendMessage(hWnd, WM_SETFONT, hFont, true)
end sub
'-----------------------------------------------------------------
% id_button=1000
sys h_Font
sub WinMain()
MSG msg
'WNDCLASSEX wc
'GetClassInfoEx(hInstance, "#32770", &wc)
sys hMainDlg = CreateNew(Dialog_Box, "Hello World", null, null, 100, 100, 400,400, WS_OVERLAPPEDWINDOW or DS_CENTER) 'DS_CENTER has no effect
sys hButton_Ok = CreateNew("Button", "Ok", hMainDlg, id_button, 160, 300, 80, 30)
h_Font = makefont("Courier New")
setfont(hButton_OK, h_Font)
SetWindowLongPtr(hMainDlg, DWL_DLGPROC, @DlgProc)
ShowWindow(hMainDlg, SW_NORMAL)
'
'Event loop:
sys bRet
'
while (bRet := GetMessage(&Msg, NULL, 0, 0)) != 0
if bRet = -1 then
'show an error message
print "Error in Message Loop"
end
else
if not IsDialogMessage(hMainDlg, &Msg) then
TranslateMessage(&Msg)
DispatchMessage(&Msg)
end if
end if
wend
end sub
function DlgProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback
printl uMsg
select case uMsg
case WM_INITDIALOG
printl "Is not valid for this kind of dialog"
printl "Enter ..." : waitkey
case WM_COMMAND
select case loword(wParam)
case IDCANCEL
DestroyWindow( hDlg )
case id_button
mbox "ok"
end select
case WM_SIZE
printl "WM_SIZE"
case WM_CLOSE
DeleteObject(h_Font)
DestroyWindow( hDlg )
case WM_DESTROY
PostQuitMessage( null )
end select
return 0
end function
WinMain()
I have not found this approach until now in Internet, therefore I am not sure if this way is correct at all. The app seems to work but I am not sure if I have to remove the pointer to dlgproc at some point. I am also not sure if I can use SetProp/RemoveProp, SetWindowSubclass/RemoveWindowSubclass for these purposes.
It seems investigation must go on. Perhaps someone has already used this class of dialog box and can help out a bit?
Roland
-
There is not any advantage in using that predefined window class with CreateWindowEx. It is intended to be used by CreateDialog. If you want a dialog, then use CreateDialog; if you want a main frame, then use CreateWindowEx with your own registered class. Using CreatewindowEx with the #32770 class is a poor attempt to save to write the code needed to register a window class.
-
Hi José,
somehow I agree, but I also somehow suspect that this approach is used in some other programming language(s) too. I was confused that WM_INITDIALOG is used in these cases, but I could simply achieve this with:
...
SetWindowLongPtr(hMainDlg, DWL_DLGPROC, @DlgProc)
SendMessage(hMainDlg, WM_INITDIALOG)
...
Of course the simplest way is to use resources of a .rc file. But Oxygenbasic is good enough to experiment a little bit with the existing possibilites of MS Windows.
Roland