• Welcome to Theos PowerBasic Museum 2017.

RaiseEvent From WndProc()

Started by Frederick J. Harris, October 18, 2010, 04:06:37 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

James C. Fuller

Quote from: José Roca on October 19, 2010, 02:39:02 AM

It's not a matter of poping that parameter from the stack, but that Windows will call the method without passig the pthis parameter, and without it, it will crash.

Even C++ programmers that use classes for the GUI, have to put the window class procedure outside the class.


All the encapsulation code I've seen uses a c++ Friend Function for the callback.

James

Frederick J. Harris

Funny you should mention that James!  I had just been playing with that yesterday.  I don't much like it.  To me its convoluted and ugly, and comes in around three times the size of plain SDK.
Note 'friend' just below in CWindow.

#include <windows.h>


class CWindow
{
public:
CWindow(HINSTANCE);
~CWindow(void);
friend LRESULT __stdcall fnWndProc(HWND, UINT, WPARAM, LPARAM);
HWND Window(void);
HINSTANCE Instance(void);
BOOL Initialize(void);
BOOL Create(int);
WPARAM MessageLoop(void);

private:
HINSTANCE   m_hInst;
HWND        m_hWnd;
};


long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam,LPARAM lParam)
{
if(msg==WM_DESTROY)
{
    PostQuitMessage(0);
    return 0;
}

return (DefWindowProc(hwnd, msg, wParam, lParam));
}


CWindow::CWindow(HINSTANCE hIns)
{
this->m_hInst=hIns;
}


CWindow::~CWindow()
{
//Entering CWindow Destructor!
}


HWND CWindow::Window()
{
return this->m_hWnd;
}


HINSTANCE CWindow::Instance()
{
return this->m_hInst;
}


BOOL CWindow::Initialize(void)
{
char szClassName[]="Form1";
WNDCLASSEX wc;

wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_HREDRAW | CS_VREDRAW;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=this->m_hInst;
wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
if(!RegisterClassEx(&wc))
    return FALSE;

return TRUE;
}


BOOL CWindow::Create(int iShow)
{
this->m_hWnd=CreateWindowEx(0,"Form1","Form1",WS_OVERLAPPEDWINDOW,100,100,350,300,HWND_DESKTOP,0,this->m_hInst,0);
ShowWindow(this->m_hWnd,iShow);
return (int)this->m_hWnd;
}


WPARAM CWindow::MessageLoop(void)
{
MSG msg;

while(GetMessage(&msg,NULL,0,0))
{
   TranslateMessage(&msg);
   DispatchMessage(&msg);
}

return msg.wParam;
}


int __stdcall WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
WPARAM wRet;

CWindow* pWnd=new CWindow(hIns);
pWnd->Initialize();
pWnd->Create(iShow);
wRet=pWnd->MessageLoop();
delete pWnd;

return wRet;
}


I'll tell ya what really hurts though.  That Com Control example of mine I posted down on my board can be done with the C++ Active Template Library ( ATL ) in about 10 minutes.  And its a 'Full' Visual ActiveX Control that is loaded into VB from the 'Controls' Tab, it shows up in the VB Toolbox with whatever icon you paint for it, can be drug and pasted onto a Form, and the properties set in the VB Property Window.  It implements all those OLE Interfaces related to embedding within a control container.  Microsoft pulled out all the stops when they built ATL to make it as efficient as possible.  It doesn't even link with the C runtime to save file size.  Even with all the stuff implemented that control comes in only around 40K.  All I can say is you have to 'give the devil his due'.  Of course it has to run in a control container.  I'll have to see if it works in Jose's.  I expect it will. 

Dominic Mitchell

Quote
pthis, wMsg, wParam and lParam

Let me muddy the waters a bit.
There are two cases when Windows(the COM subsystem) will call your ActiveX control
passing the values shown above.
The first case is when a windowed ActiveX control acts as a container for other controls
and implements the ISimpleFrameSite interface. The COM subsystem calls the PreMessageFilter
and PostMessageFilter methods of this interface passing the values

pthis, hWnd, wMsg, wParam, lParam, [p]lResult and [p]dwCookie.

The second case is when the ActiveX control is windowless. A windowless control does not have
a window procedure, but implements the IOleInPlaceObjectWindowless interface in its place.
The COM subsystem calls the OnWindowMessage method of this interface passing the values

pthis, hWnd, wMsg, wParam, lParam, plResult.

Here hWnd is the window handle of the OLE container.
The windowless control should call the OnDefWindowMessage mehod of the IOleInPlaceSiteWindowless
interface implemented by the container to obtain the default windows processing of the container.

Given the above information, if you want to use a PowerBASIC class, your only option is to write a
windowless control.

If you have ever written a control from the scratch, that is not piggybacking on a predefined control,
then you already know how to write the non-COM part of a windowless control.
Dominic Mitchell
Phoenix Visual Designer
http://www.phnxthunder.com