April 29, 2024, 09:19:47 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


window using winapi functions?

Started by fasecero, December 13, 2008, 11:54:30 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

fasecero

I'm wondering if we could make a window just using winapi functions in EB. I mean using...

_RegisterClassEx (...)
_CreateWindowEx(...)
_ShowWindow (...)

...and so on.
All this functions are declared in windows.inc. But in MSDN, all of them are put inside a WinMain function that's not appear in the include.
So, is it possible? We have to declare this WinMain in some way?
Just curiosity :)

Ionic Wind Support Team

No need for winmain.  The startup routines are already part of your executable.

In a project $main indicates the starting address, and in a single file compile execution starts on the first code in the file.

And of course you can do it the API way, if you wish.  OpenWindow registers a class with RegisterClassEx, creates the window with CreateWindowEx, etc. 

Paul.
Ionic Wind Support Team

fasecero

I see, but _RegisterClassEx(...) require a hInstance member (param of WinMain), how can i get this hinstance?

LarryMc

EXTERN _hinstance as UINT 

that will do it.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Yep.  _hinstance is a global variable that is automatically set by the internal startup routines.

In reality Windows doesn't call a "winmain" function.   Microsoft assumes in all of their documentation that you are using a C/C++ compiler, whose startup routine calls WinMain after getting the process instance with GetModuleHandle.   All Windows does is load your executable, sets a few environment variables and does a CALL of the entry point specified by the linker. No parameters are pushed by Windows since the stack is owned by your processes address space.

So a C compiler entry point does this:

hinstance = GetModuleHandle(NULL)
pCommandLine = GetCommandLine()
GetStartupInfo(&info)
WinMain(hinstance,NULL,pCommandLine,info.dwFlags)

The Emergence and Aurora entry points are a little more streamlined.  They do save off _hinstance using GetModuleHandle, create the processes heap which is used for string functions and returning UDT's from functions, and then call the users code.   If your interested in the other information just use the same API functions.

Paul.



Ionic Wind Support Team

fasecero

Ok. Thx Paul, Larry for yours fast answers. It's really cool see other people ready to help. The explanations was clear and i have a window created just with winapi functions. But i will use the OPENWINDOW anyway, just wanted to learn a little more.

fasecero

December 14, 2008, 03:59:13 AM #6 Last Edit: December 14, 2008, 04:12:44 AM by fasecero
Ehm, my example only works with a "predefined" class in CreateWindowEx, but if i want to create my own class it fails. Here is the code:



/* WINDOW CREATED WITH WINAPI FUNCTIONS  */
/* THE WINDOW IS NOT CREATED  */
/* ONLY IS CREATED WITH A PREDEFINED CLASS, FOR EXAMPLE: "BUTTON"  */
/* CAREFULLY, IN THIS CASE THE WINPROC IT IS NOT RECOGNIZED  */

$INCLUDE "windows.inc"


' DECLARE THE VARIABLES
EXTERN _hinstance as UINT ' instance
DEF hwnd AS INT ' windows handle
DEF wincl AS WNDCLASSEX ' type for windowclass
DEF messages AS MSG
DEF ClassName as STRING ' class name
DEF pClassName as POINTER ' pointer to class name


' DEFINITION OF THE CLASS NAME AND A POINTER TO IT
ClassName="MyWindow"
pClassName=ClassName
DEBUGPRINT "pClassName point to: "+#<STRING>pClassName ' just to see if is ok


' INIT THE WNDCLASSEX
wincl.lpszClassName=pClassName /* class name */

wincl.hInstance = _hinstance
wincl.lpfnWndProc = &WinProc /* windows procedure */
wincl.style = CS_DBLCLKS /* Catch double-clicks */
wincl.cbSize = LEN(WNDCLASSEX)
wincl.lpszMenuName = 0 /* no menÃÆ'Ã,º */
wincl.cbClsExtra = 0 /* No extra bytes after the window class */
wincl.cbWndExtra = 0 /* structure or the window instance */
wincl.hbrBackground = COLOR_BACKGROUND


' REGISTER THE CLASS
IF _RegisterClassEx (wincl)=0 THEN
DEBUGPRINT "Can't register the class"
END
ENDIF


' CREATE THE WINDOW
hwnd = _CreateWindowEx (0, ClassName , "Caption", WS_OVERLAPPEDWINDOW, 100, 100, 300, 200, HWND_DESKTOP, 0, _hinstance, 0)
IF hwnd=0 THEN
DEBUGPRINT "Can't create the window"
END
ENDIF


' SHOW THE WINDOW
_ShowWindow (hwnd, SW_SHOW)


' MAIN LOOP
WHILE (_GetMessage (messages, 0, 0, 0))
/* Translate virtual-key messages into character messages */
_TranslateMessage(messages)
/* Send message to WindowProcedure */
_DispatchMessage(messages)
ENDWHILE


' WINDOW PROCEDURE
SUB WinProc(hWnd:INT,uMsg:INT,wParam:INT,lParam:INT),INT
SELECT uMsg
CASE @IDCLOSEWINDOW
_PostQuitMessage (0)
ENDSELECT
RETURN
ENDSUB



CreateWindowEx fail and it seems that the problem is with the ClassName...
Work putting a "predefined" class in CreateWindowEx, but in this case the Window Procedure it is not recognized.

sapero

Fasecero, you need to invoke default actions to at least display the window on the screen. The message WM_NCPAINT would draw window caption and borders, but if you return just zero, it will be not drawn.

SUB WinProc(hWnd:INT,uMsg:INT,wParam:INT,lParam:INT),INT
SELECT uMsg
CASE WM_CLOSE
_DestroyWindow(hWnd) ' close the window now
_PostQuitMessage (0)

' any unhandled message goes here
DEFAULT
RETURN _DefWindowProc(hWnd, uMsg, wParam, lParam)
ENDSELECT
RETURN 0
ENDSUB

fasecero

yes, it's work now!. Txh so much, sapero, i'm never will discover this mistake by my own.

fasecero

one more thing, the function:

wincl.hIcon = _LoadIcon (0, IDI_APPLICATION)

seems not to work because the second param is of type STRING, so how can i cast the IDI_APPLICATION to STRING ( str$(...) not work ) ?

Ionic Wind Support Team

Use your own declaration.

declare import, LoadIcon(hinstance is int, id as pointer),uint

Or use the built in LoadImage function.

Paul.
Ionic Wind Support Team

fasecero

December 14, 2008, 12:13:53 PM #11 Last Edit: December 14, 2008, 12:57:41 PM by fasecero
Ok, this is finally the complete code... now i like still more the OPENWINDOW  :)
Thx again to all.



/* WINDOW CREATED WITH WINAPI FUNCTIONS  */

$INCLUDE "windows.inc"


' REDECLARING SOME FUNCTIONS WITH SECOND PARAM AS POINTER, NOT STRING
DECLARE "user32.dll",LoadIcon ALIAS "LoadIconA"(hinstance:INT, id:pointer),uint
DECLARE "user32.dll",LoadCursor ALIAS "LoadCursorA"(hinstance:INT, id:pointer),uint


' DECLARE THE VARIABLES
STRING pCommandLine
STARTUPINFO info
DEF hwnd AS INT ' windows handle
DEF wincl AS WNDCLASSEX ' type for windowclass
DEF messages AS MSG
DEF ClassName as STRING ' class name
DEF pClassName as POINTER ' pointer to class name
ClassName="MyWindow"
pClassName=ClassName


' INIT THE <WINMAIN> STUFF
EXTERN _hinstance as UINT
pCommandLine = _GetCommandLine()
_GetStartupInfo(info)

' INIT THE WNDCLASSEX
wincl.lpszClassName=pClassName /* class name */
wincl.hInstance = _hinstance
wincl.lpfnWndProc = &WinProc /* windows procedure */
wincl.style = CS_DBLCLKS /* Catch double-clicks */
wincl.cbSize = LEN(WNDCLASSEX)
wincl.lpszMenuName = 0 /* no menÃÆ'Ã,º */
wincl.cbClsExtra = 0 /* No extra bytes after the window class */
wincl.cbWndExtra = 0 /* structure or the window instance */
wincl.hbrBackground = COLOR_BACKGROUND
wincl.hIcon=LoadIcon(0, IDI_APPLICATION)
wincl.hIconSm = LoadIcon(0, IDI_APPLICATION)
wincl.hCursor = LoadCursor(0, IDC_ARROW)


' REGISTER THE CLASS
IF _RegisterClassEx (wincl)=0 THEN
DebugText("Can't register the class")
END
ELSE
DebugText("Registering the class: OK")
ENDIF


' CREATE THE WINDOW
hwnd = _CreateWindowEx (0, ClassName , "Caption", WS_OVERLAPPEDWINDOW, 100, 100, 300, 200, HWND_DESKTOP, 0, _hinstance, 0)
IF hwnd=0 THEN
DebugText("Can't create the window")
END
ELSE
DebugText("Creating the window: OK")
ENDIF


' SHOW THE WINDOW
_ShowWindow (hwnd, info.dwFlags)


' MAIN LOOP
WHILE (_GetMessage (messages, 0, 0, 0))
/* Translate virtual-key messages into character messages */
_TranslateMessage(messages)
/* Send message to WindowProcedure */
_DispatchMessage(messages)
ENDWHILE
END


' WINDOW PROCEDURE
SUB WinProc(hWnd:INT,uMsg:INT,wParam:INT,lParam:INT),INT
SELECT uMsg
CASE @IDCREATE
'
CASE @IDDESTROY
_PostQuitMessage (0)
' any unhandled message goes here
DEFAULT
RETURN _DefWindowProc(hWnd, uMsg, wParam, lParam)
ENDSELECT
RETURN 0
ENDSUB


' FUNCTION TO OUTPUTS A STRING TO THE DEBUG VIEW ONLY IF WE ARE IN DEBUG MODE
SUB DebugText(string text)
$IFDEF DEBUG
DEBUGPRINT text
$ENDIF
ENDSUB



Ionic Wind Support Team

Well at least you learned something ;)

OpenWindow does a lot more than just creating a single window type.  It handles MDI windows, MDI children, double buffering, etc.
Ionic Wind Support Team

aurelCB

Here i will present my version of created window with API functions and
in next i will try create double buffered window .

/* WINDOW CREATED WITH WINAPI FUNCTIONS  */
$INCLUDE "windows.inc"

Type WNDCLASSEX
  INT cbSize       
  INT Style         
  POINTER lpfnwndproc   
  INT cbClsextra   
  INT cbWndExtra   
  INT hInstance     
  INT hIcon         
  INT hIconSm       
  INT hCursor       
  INT hbrBackground
  INT lpszMenuName 
  POINTER pszClassName
EndType

'API FUNCTIONS
DECLARE "user32.dll",LoadIcon ALIAS "LoadIconA"(hinstance:INT, id:pointer),uint
DECLARE "user32.dll",LoadCursor ALIAS "LoadCursorA"(hinstance:INT, id:pointer),uint
DECLARE "user32.dll", GetModuleHandle ALIAS GetModuleHandleA(lpModuleName AS POINTER),INT
DECLARE "gdi32.dll" ,CreateSolidBrush(crColor AS INT),INT
DECLARE "user32.dll", RegisterClassEx ALIAS RegisterClassExA(pcWndClassEx AS WNDCLASSEX),WORD
DECLARE "user32.dll", GetSysColor(nIndex AS INT),INT
DECLARE "gdi32.dll",BitBlt(hDestDC AS INT,x AS INT,y AS INT,nWidth AS INT,nHeight AS INT,hSrcDC AS INT,xSrc AS INT,ySrc AS INT,dwRop AS INT),INT

DEF hwnd AS INT ' windows handle
DEF wcx AS WNDCLASSEX ' type for windowclass
DEF _hinstance as INT
DEF messages AS MSG
DEF ClassName as STRING ' class name
DEF pClassName as POINTER ' pointer to class name
ClassName="MyWindow"
pClassName=ClassName

' FILL THE WNDCLASSEX
hinstance = GetModuleHandle(0)
wcx.lpszClassName=pClassName /* class name */
wcx.hInstance = hinstance
wcx.lpfnWndProc = &WinProc   /* windows procedure */
wcx.style = CS_DBLCLKS | CS_OWNDC      /* Catch double-clicks */
wcx.cbSize = LEN(WNDCLASSEX)
wcx.lpszMenuName = 0 /* no menu */
wcx.cbClsExtra = 0 /* No extra bytes after the window class */
wcx.cbWndExtra = 0 /* structure or the window instance */
wcx.hbrBackground = CreateSolidBrush(GetSysColor(15))  'buttonFace backColor
wcx.hIcon=LoadIcon(0, IDI_APPLICATION)
wcx.hIconSm = LoadIcon(0, IDI_APPLICATION)
wcx.hCursor = LoadCursor(0, IDC_ARROW)

' REGISTER CLASSEX
RegisterClassEx (wcx)

' CREATE WINDOW
hwnd = _CreateWindowEx (0, ClassName , "WINAPI window", WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, HWND_DESKTOP, 0, hinstance, 0)
' SHOW THE WINDOW
_ShowWindow (hwnd, SW_SHOW)


' Message Loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WHILE (_GetMessage (messages, 0, 0, 0))
    _TranslateMessage(messages)
    _DispatchMessage(messages)
WEND
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
END


' WINDOW PROCEDURE
SUB WinProc(hWnd:INT,uMsg:INT,wParam:INT,lParam:INT),INT
SELECT uMsg
CASE WM_PAINT
'
CASE WM_DESTROY
_PostQuitMessage (0)

DEFAULT
RETURN _DefWindowProc(hWnd, uMsg, wParam, lParam)
ENDSELECT
RETURN 0
ENDSUB