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
 |