How To Create Window with CreateWindowEx ?
Archives Forums/Win32 Discussion/How To Create Window with CreateWindowEx ?
| ||
| I fail badly when i try to create a window with this api-call. here is the code: (i am sure there are lot of bugs or so, but the compiler does not complain) |
| ||
| dont you need to create a WNDCLASSEX structure and call RegisterClassEx before calling the createwindow function ? |
| ||
| good question! is there anybody who have basic winapi knowledge with some bm examples? |
| ||
| I just checked in the msdn, it says you need to register the class before makking a call to createwindow. |
| ||
| Ok, thank you very much. I will post the next error in a few minutes as i will make some errors^^. 1st problem: msdn say: he RegisterClassEx function registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. Syntax ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx ); Parameters lpwcx [in] Pointer to a WNDCLASSEX structure. You must fill the structure with the appropriate class attributes before passing it to the function. WNDCLASSEX should look like this: typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX, *PWNDCLASSEX; How to do this in BM? |
| ||
| lol yeah, that is where I fell over :) I am sure someone here knows how :) |
| ||
heres a c function from my max gui module thats still in development.
// The name of our window class.
TCHAR szClassName[] = TEXT("MicroMax_CLASS") ;
//
int CLASS_GOOD;
// Creates GUI Window.
int MicroMax_CreateWindow(LPCTSTR szWindowText,int x,int y,int width,int height,int group,int flags){
HINSTANCE hThisInstance = GetModuleHandle(0);
if(!CLASS_GOOD){
// Window class structure.
WNDCLASSEX wcx ;
// Now we must fill in the members of WNDCLASSEX.
wcx.hInstance = hThisInstance;
wcx.lpszClassName = szClassName ;
wcx.lpfnWndProc = (WNDPROC)MicoMaxWinProc;
wcx.style = CS_DBLCLKS;
wcx.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wcx.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor (NULL, IDC_ARROW);
wcx.lpszMenuName = NULL;
wcx.cbSize = sizeof (WNDCLASSEX);
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hbrBackground = GetSysColorBrush(COLOR_3DFACE) ;
// Register our window class with the operating system.
// If there is an error, exit program.
if ( !RegisterClassEx (&wcx) )
{
MessageBox( 0, TEXT("Failed to register window class!"),TEXT("Error!"), MB_OK|MB_ICONERROR ) ;
return 0;
}
// class created.
CLASS_GOOD = TRUE;
}
//
int child_window=1;
if(!group){
group = (int)HWND_DESKTOP;
child_window=0;
}else{
child_window=1;
}
HWND hwnd = CreateWindowEx ( 0, szClassName, szWindowText, WS_OVERLAPPEDWINDOW|WS_VISIBLE, x, y, width, height,(HWND)group, 0, hThisInstance, 0 );
if(child_window==1){
SetParent(hwnd,(HWND)group);
}
if ( !IsWindow(hwnd) ) {
return 0;
}
return (int)hwnd;
}
kev |
| ||
here is my feeble attempt, maybe it might help :(
Global CreateWindowEx(window,Title$z,message$z, flags,x,y,w,h,Parent,guiid, hInstance,dunno);
Global RegisterClassEx(wndclassex:WNDCLASSEX);
Global GetModuleHandle(modname$);
Const WS_OVERLAPPED = 0
Const WS_VISIBLE = $10000000
user32 = LoadLibraryA ("user32.dll")
Kernel32 = LoadLibraryA ("Kernel32.dll")
If user32=Null
Notify("Konnte user32.dll nicht laden.")
Else
CreateWindowEx=GetProcAddress(user32,"CreateWindowExA")
RegisterClassEx=GetProcAddress(user32,"RegisterClassExA")
GetModuleHandle=GetProcAddress(Kernel32,"GetModuleHandleA")
EndIf
If user32=Null
Notify("Konnte Kernel32.dll nicht laden.")
Else
GetModuleHandle=GetProcAddress(Kernel32,"GetModuleHandleA")
EndIf
myInstance% = GetModuleHandle(Null)
Type WNDCLASSEX
Field size%
Field style%
Field lpfnWndProc%
Field extra%
Field wndExtra%
Field hInstance%
Field hIcon%
Field hCursor%
Field bg%
Field menuname$
Field classname$
Field hIconSm%
End Type
wnd:WNDCLASSEX = New WNDCLASSEX
wnd.size = SizeOf(WNDCLASSEX)
wnd.style = CS_HREDRAW
wnd.lpfnWndProc = Null
wnd.extra = DLGWINDOWEXTRA
wnd.wndExtra=0
wnd.hInstance = myInstance
wnd.hIcon=0
wnd.hCursor=0
wnd.bg=COLOR_WINDOW
wnd.menuname=Null
wnd.classname="test"
wnd.hiconsm=Null
If Not RegisterClassEx(wnd) Then Notify("could not register class")
If Not CreateWindowEx(0,"test","test window",WS_OVERLAPPED | WS_VISIBLE,0,0,640,480,0,0,myInstance ,Null) Then Notify("could not create window")
While Not KeyDown(KEY_ESCAPE)
Wend
|
| ||
| without testing Deux example, wnd.lpfnWndProc needs to be an address of a function. some thing like this, we need the address of the winproc. Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) End Function kev |
| ||
| yeah, I just rearranged code, never really tested it myself, sorry for not doing that. I have been looking at the user32.bmx code, and I think that may be helpful for regaa, the constants and functions you need are in there I think. |
| ||
here you go a working example using just blitzmax, this creates a window and waits for the close button.Import "-luser32" Extern Function GetSysColorBrush:Int(nIndex:Int) = "GetSysColorBrush@4" End Extern Const COLOR_BTNFACE = 15 Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Local classname$ = "WindowCLASS" Local CLASSNAME_ADRR:Byte Ptr = Byte Ptr classname$ Local class:WNDCLASS = New WNDCLASS Local classADDR:Byte Ptr = Byte Ptr class class.hInstance = GetModuleHandleA(0) class.lpfnWndProc = WinProcADDR class.lpszClassName = CLASSNAME_ADRR class.hbrBackground = GetSysColorBrush(COLOR_BTNFACE) If(RegisterClassA(classADDR) <> Null) Then Print "class reg ok" EndIf Local message:MSG = New MSG Local messageADDR:Byte Ptr = Byte Ptr message Local windowTitle$ = "Testing" Local windowTitleADDR:Byte Ptr = Byte Ptr windowTitle$ Const WS_CAPTION = $C00000 Const WS_SYSMENU = $80000 Const WS_VISIBLE = $10000000 Const WS_MINIMIZEBOX = $20000 Const WS_MAXIMIZEBOX = $10000 Const WM_DESTROY = 2 Local lpParamADDR:Byte Ptr Local window = CreateWindowExA( 0,CLASSNAME_ADRR,windowTitleADDR,WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_VISIBLE,100,100,200,200,0,0,GetModuleHandleA(0),lpParamADDR ) While Not KeyDown(KEY_ESCAPE) GetMessageA(messageADDR,0,0,0) TranslateMessage(messageADDR) DispatchMessageA(messageADDR) Wend ' ' ' Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) Select Msg Case WM_DESTROY Notify "Bye!" End End Select Return DefWindowProcA(hWnd,Msg,wParam,lParam) End Function needs cleaning up. kev. |
| ||
| many thanks to that much examples. i will check'em out. god job dudes :P |
| ||
| Very cool kev. Thanks! |
| ||
| I tryed to extend some parts, but whenever i use SendMessage (declared in user32.bmx) i get this error: undefined reference to `SendMessage@16 :( |
| ||
| regaa im not sure why you get the error, but this will work. add the sendmessage to the extern ... end extern Function SendMessage:Int(hWnd:Int,MSG:Int,wParam:Int,lParam:Int) = "SendMessageA@16" then to test use SendMessage window,WM_DESTROY,0,0 after creating the window. kev |
| ||
| Thank you very much. I've learned some important BM basics :p . |
| ||
| wow very cool, awsome kev ! Thanks |
| ||
| Here's one with some buttons and a keypress - you can press [ESC] to quit. |
| ||
| just to make a note, under WM_COMMAND the HIWORD(wParam) specifies the notification code if the message is from a control, this will be 0 if the message is from a menu, the ID of the menu is found in the LOWORD(wParam) heres 2 functions to get the low and hi words. Function LOWORD(value) Return value And $FFFF End Function Function HIWORD(value) Return (value Shr 16) End Function kev |
| ||
| I'm trying to add a font, but my CreateFont call makes Blitz quit: |
| ||
| I can add a font to ONE control using this code, adding the font to more than one control makes Blitz quit: |
| ||
this is how i do it in winblitz3d. you shold be able to convert this easy.Function OpenFont(fontname$,width=12,height=8,bold=0,italic=0,underline=0) font = apiCreateFont(width,height,0,0,bold,underline,0,0,0,0,0,0,0,GRAB_StringAddr(fontname$)) Return font End Function Function Usefont(gadget,font) hdc = apiGetWindowDC(gadget) hfontprev = apiSelectObject(hdc,font) apiSendMessage gadget,WM_SETFONT,apiSelectObject(hdc,font),1 End Function kev |
| ||
| Thanks, kev. I see I've been doing it all wrong, I'll make those SelectObject() changes and try again. |
| ||
| I'm still having troubles: http://www.blitzbasic.com/Community/posts.php?topic=50237 :) |
| ||
btw : LOWORD needs to be changed to: ("&" not "AND" )Function LOWORD(value) Return value & $FFFF End Function |
| ||
| Hi, I'm late... Can anyone make this code by Kev work with the latest version of BlitzMax : Import "-luser32" Extern Function GetSysColorBrush:Int(nIndex:Int) = "GetSysColorBrush@4" End Extern Const COLOR_BTNFACE = 15 Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Local classname$ = "WindowCLASS" Local CLASSNAME_ADRR:Byte Ptr = Byte Ptr classname$ Local class:WNDCLASS = New WNDCLASS Local classADDR:Byte Ptr = Byte Ptr class class.hInstance = GetModuleHandleA(0) class.lpfnWndProc = WinProcADDR class.lpszClassName = CLASSNAME_ADRR class.hbrBackground = GetSysColorBrush(COLOR_BTNFACE) If(RegisterClassA(classADDR) <> Null) Then Print "class reg ok" EndIf Local message:MSG = New MSG Local messageADDR:Byte Ptr = Byte Ptr message Local windowTitle$ = "Testing" Local windowTitleADDR:Byte Ptr = Byte Ptr windowTitle$ Const WS_CAPTION = $C00000 Const WS_SYSMENU = $80000 Const WS_VISIBLE = $10000000 Const WS_MINIMIZEBOX = $20000 Const WS_MAXIMIZEBOX = $10000 Const WM_DESTROY = 2 Local lpParamADDR:Byte Ptr Local window = CreateWindowExA( 0,CLASSNAME_ADRR,windowTitleADDR,WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_VISIBLE,100,100,200,200,0,0,GetModuleHandleA(0),lpParamADDR ) While Not KeyDown(KEY_ESCAPE) GetMessageA(messageADDR,0,0,0) TranslateMessage(messageADDR) DispatchMessageA(messageADDR) Wend ' ' ' Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) Select Msg Case WM_DESTROY Notify "Bye!" End End Select Return DefWindowProcA(hWnd,Msg,wParam,lParam) End Function This would be great :) |
| ||
| Just to clarify ;) you all know that these functions are already shipped with Blitzmax? If not, then take a look to the pub.win32 module. this module already gives you everything you need (structs and functions) for these things. |
| ||
| Thanks, I'll take a look :) |
| ||
hm, there is an Problem with the Maximize
Strict
Framework PUB.Win32
Import BRL.System
Import BRL.EventQueue
Import BRL.basic
Extern "Win32"
Function UpdateWindow(hWnd)
End Extern
Global CLASS_NAME:Byte Ptr="bbW32 Window".ToCString() ' Wie heißt unsere Anwendung
Global hinst=GetModuleHandleA(0) ' was ist uinsere instance
Local hwnd%=CreateHWND(600,400,0,"Jan_'s Win32 Application".ToCString()) ' Fenster erstellen
'showwindow(hwnd,sw_show) ' fenster Zeigen
'showwindow(hwnd,sw_hide) ' fenster verstecken
Local ende%
Repeat
WaitEvent() ' warten, das was passiert, das wichtig ist --> 0% CPU last
ende=True
Until (ende=True)
DestroyWindow(hWnd) ' das Fenster wieder löschen
End
Function WndProc( hwnd,message,wp,lp ) "win32"
Local event:TEvent
Select message ' hier reagieren wir auf die aktionen die der nutzer auslöst
Case WM_CLOSE ' schließen
event=New TEvent
PostEvent(event) ' so, das sendet an Waitevent das es was machen soll (siehe oben)
postquitmessage(0)
DestroyWindow(hWnd)
End
Return
Case WM_DESTROY ' zerstören
event=New TEvent
PostEvent(event) ' so, das sendet an Waitevent das es was machen soll (siehe oben)
postquitmessage(0)
DestroyWindow(hWnd)
End
Return
Case WM_MOVE ' bewegen
'updatewindow(hwnd)
Return
Case WM_SIZE
'bbSystemEmitOSEvent hwnd,message,wp,lp,Null
'updatewindow(hwnd)
Return
Case WM_Paint
updatewindow(hwnd)
Return
' Case WM_MOUSEMOVE
'Default
'bbSystemEmitOSEvent hwnd,message,wp,lp,Null
End Select
Return DefWindowProcA( hwnd,message,wp,lp )
End Function
Function CreateHWND(width,height,fullscreen,WINDOW_TITLE:Byte Ptr,PosX%=100,PosY%=100) ' Fenster erstellen
Local style,ex_style,hwnd
Local hinst=GetModuleHandleA(0)
Global wndClas
If Not wndClas
Local wc:WNDCLASS=New WNDCLASS
Local hinst=GetModuleHandleA(0)
'Local icon:Byte Ptr="IDI_INFORMATION".ToCString()
wc.style=CS_HREDRAW Or CS_VREDRAW ' Fensterstyle
wc.lpfnWndProc=WndProc 'Zeiger auf die Fensterprozedur
wc.cbClsExtra=0
wc.cbWndExtra=0
wc.hInstance=hinst ' Instanz des Programms
wc.hIcon=LoadIconA(Null, Null) 'Handle eines Icons das z.B. mit LoadIcon() geladen wurde
wc.hbrBackground = GetStockObject (LTGRAY_BRUSH)
wc.hCursor=LoadCursorA( Null,Byte Ptr IDC_ARROW ) 'Handle eines Cursors
wc.lpszClassName=CLASS_NAME ' Name der zu registrierenden Fensterklasse
wndClas=RegisterClassA( wc )
If Not wndClas
Throw "Failed to register window class"
EndIf
EndIf
ex_style=WS_EX_TRANSPARENT
style=WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX'|WS_SYSMENU
Local rect[]=[posx,posy,width+posx,height+posy]
hWnd=CreateWindowExA(..
ex_style,..
CLASS_NAME,..
WINDOW_TITLE,..
style,..
posx,posy,width,height,..
0,0,hinst,Null)
ShowWindow(hWnd,SW_SHOW);
MemFree WINDOW_TITLE
If Not hwnd Throw "Failed to create window"
Return hwnd
End Function
|