https://www.freebasic.net/forum/viewtopic.php?f=7&t=13451&p=280321#p280320
Sorry for posting FreeBasic stuff here, but I am really surprised that this works - it looks very unusual :rolleyes:
Mr Petzold, any opinion?
#Include "windows.bi"
Dim As MSG msg
Dim As HWND Window_Main, Edit1, Edit2, Button1, Button2, List1
Dim As HFONT Font ,cFont
Dim As HMENU hMenu, hDatei, hHilfe
Dim As Integer i,icon1
Dim As ZString*1024 text
const ICONBUTTON = 1409351744
'Window with all controls:
Window_Main = CreateWindow("#32770", "Windows GUI", WS_OVERLAPPEDWindow Or WS_VISIBLE, _
100, 100, 500, 650, 0, 0, 0, 0 )
Var Label = CreateWindow("STATIC", "Enter a text:", WS_VISIBLE Or WS_CHILD, _
20, 20, 200, 20, Window_Main, 0, 0, 0)
Edit1 = CreateWindow("EDIT", "", WS_BORDER Or WS_VISIBLE Or WS_CHILD Or ES_AUTOHSCROLL, _
20, 50, 200, 20, Window_Main, 0, 0, 0 )
Button1 = CreateWindow("BUTTON", "Copy", WS_VISIBLE Or WS_CHILD, _
60, 80, 100, 32, Window_Main, 0, 0, 0 )
Edit2 = CreateWindow("EDIT", "", _
WS_BORDER Or WS_VISIBLE Or WS_CHILD Or WS_HSCROLL Or WS_VSCROLL Or ES_MULTILINE Or ES_WANTRETURN, _
20, 120, 300, 200, Window_Main, 0, 0, 0 )
Button2 = CreateWindow("BUTTON", "Copy", ICONBUTTON, 340, 200, 100, 32, Window_Main, 0, 0, 0 )
icon1 = LoadImage(0, "fbButtonIcon.ico", IMAGE_ICON, 98, 28, 24) 'Icon via resource name
SendMessage(Button2, 247, 1, icon1)
List1 = CreateWindow("LISTBOX", "", _
WS_BORDER Or WS_VISIBLE Or WS_CHILD Or WS_HSCROLL Or WS_VSCROLL, _
20, 350, 200, 200, Window_Main, 0, 0, 0 )
'Font to be used for the multiline editbox:
Font = CreateFont(16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New")
cFont = CreateFont(16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Consolas")
SendMessage(Button1, WM_SETFONT, Cast(WPARAM, cFont), True)
SendMessage(List1, WM_SETFONT, Cast(WPARAM, cFont), True)
SendMessage(Edit2, WM_SETFONT, Cast(WPARAM, Font), True)
SetWindowText(Edit2, "Please write text here!")
'Add items to listbox:
For i = 0 To 20
text = "Item number " + Str(i)
SendMessage(List1, LB_ADDSTRING, 0, Cast(LPARAM, @text))
Next
'Menu:
hMenu = CreateMenu( )
hDatei = CreateMenu( )
hHilfe = CreateMenu( )
InsertMenu(hMenu, 0, MF_POPUP, CInt(hDatei), "File")
InsertMenu(hMenu, 0, MF_POPUP, CInt(hHilfe), "Help")
AppendMenu(hDatei, 0, 101, "New" )
AppendMenu(hDatei, 0, 102, "Open" )
AppendMenu(hDatei, 0, 103, "Save" )
AppendMenu(hDatei, 0, 104, "Exit" )
AppendMenu(hHilfe, 0, 105, "?")
SetMenu(Window_Main, hMenu )
'Event Loop:
Do
GetMessage(@msg, 0, 0, 0)
TranslateMessage(@msg)
DispatchMessage(@msg)
Select Case msg.hwnd
Case Window_Main
Select Case msg.message
Case WM_COMMAND 'Menu messages, including window menu
Select Case msg.wParam
Case 2
If MessageBox(0, "Do you really want to exit?", "Exit", _
MB_YESNO Or MB_ICONQUESTION) = IDYES Then Exit Do
Case 101
MessageBox(0, "New file ...", "File", 0)
Case 102
MessageBox(0, "Open file ...", "File", 0)
Case 103
MessageBox(0, "Save file ...", "File", 0)
Case 104
If MessageBox(0, "Do you really want to exit?", "File", _
MB_YESNO Or MB_ICONQUESTION) = IDYES Then Exit Do
Case 105
MessageBox(0, "Sorry, I cannot help you!", "Help", 0)
End Select
End Select
Case Button1
If msg.message = WM_LBUTTONDOWN Then
'Copy text from Edit1 to console:
GetWindowText(Edit1, text, SizeOf(text))
Print text
End If
Case Button2
If msg.message = WM_LBUTTONDOWN Then
'Copy text from Edit2 to console:
GetWindowText(Edit2, text, SizeOf(text))
text = RTrim(text)
Print text
End If
Case List1
If msg.message = WM_LBUTTONDOWN Then
'Show selected index and item from listbox:
i = SendMessage(List1, LB_GETCURSEL, 0, 0)
SendMessage(List1, LB_GETTEXT, i, Cast(LPARAM, @text))
text = RTrim(text)
Print i; Space(1); text
End If
End Select
Loop
DeleteObject(Font)
End
seem optimized version,to omit the invoke wndproc and inline it
how much faster without several pushes,call,ret ?
Just a trick, no real value.
I have seen code long ago that hid the WndProc() but it was usually a technique of branching to separate procedures (functions) for every message being processed and it was clunky and very inefficient. Hated it and never used it, always better to know what is going on than not.
José Roca told me the trick is CreateWindow("#32770", ... so it's a dialog, not a full-fledged window. Somewhat limited in that you don't have a DefWindowProc, but it works.
It is not nothing unusual nor a trick. It is as old as Windows itself.
Using the predefined "#32770" window class name you are creating a modeless dialog. You can use the API function CreateDialog instead. And you can use DialogBox to create a modal dialog.
See: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createdialoga
This is what PowerBasic uses under the hood (well, it probably will use CreateDialogIndirectParam and DialogBoxIndirectParam) to create the modal or modeless dialogs that its GUI system (called DDT - Dynamic Dialog Tools) produce.
If you want to know what the so called Windows Dialog Engine does, there is available C++ source code as implemented in ReactOS/Wine:
See: https://doxygen.reactos.org/d0/dfb/win32ss_2user_2user32_2windows_2dialog_8c_source.html
Quote from: José Roca on February 21, 2021, 01:15:47 AM
It is not nothing unusual nor a trick. It is as old as Windows itself.
Sure, and i am older than MS Windows :tongue:
#32768 The class for a menu.
#32769 The class for the desktop window.
#32770 The class for a dialog box.
#32771 The class for the task switch window.
#32772 The class for icon titles.