Author Topic: Is there a use for Window class #32770 ?  (Read 2245 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Hero Member
  • *****
  • Posts: 973
Is there a use for Window class #32770 ?
« 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:

Code: [Select]
$ 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:
Code: [Select]
$ 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

Josť Roca

  • Sr. Member
  • ****
  • Posts: 263
Re: Is there a use for Window class #32770 ?
« Reply #1 on: October 28, 2018, 03:09:02 AM »
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.

Arnold

  • Hero Member
  • *****
  • Posts: 973
Re: Is there a use for Window class #32770 ?
« Reply #2 on: October 28, 2018, 04:08:57 AM »
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