Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Creating window inside DLL

411 views
Skip to first unread message

xa...@usa.net

unread,
Jul 10, 2001, 3:48:09 AM7/10/01
to
I create additional thread inside DLL that my app uses, create main
window there and enter thread's message loop. I use following code to
create the window, but for some reason CreateWindow always fails, with
GetLastError returning 6 - Invalid handle.
g_hInstDll is a global variable containing the proper instance handle
of the DLL (stored in DLLMain DLL_PROCESS_ATTACH):

-----------------------------------------------------------------------------------------------------------------------
WNDCLASS wc;

wc.lpszClassName = "COMMCLS";
wc.lpfnWndProc = WindowProc;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.hInstance = g_hInstDll;
wc.hIcon = (HICON) LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

// Create the main window now
rval = RegisterClass(&wc); // succeeds

m_hWnd = CreateWindow("COMMCLS", "Comm",
WS_OVERLAPPEDWINDOW,
0,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL,
g_hInstDll,
NULL);

int error = GetLastError(); // returns 6 !? (m_hWnd is NULL)
-----------------------------------------------------------------------------------------------------------------------


robm

unread,
Jul 10, 2001, 10:32:01 AM7/10/01
to
try a SetLastError( 0 ) before the RegisterClass() and then
GetLastError() after RegisterClass()
i had a similar problem once, that was not detected only by
the return from RegisterClass()

i presume you are performing this inside your thread ?
how do you create the thread ?

BTW i plugged your code into a DLL thread where i have
similar functionality that you describe and
the code worked ?

HTH
rob

xa...@usa.net wrote in message
<89clkt027r68bnvhb...@4ax.com>...

Christian Kaiser

unread,
Jul 10, 2001, 5:06:37 PM7/10/01
to
Can it be that your WindowProc does not call DefWindowProc()?

Christian

<xa...@usa.net> wrote in message
news:89clkt027r68bnvhb...@4ax.com...

xa...@usa.net

unread,
Jul 11, 2001, 2:58:54 AM7/11/01
to
On Tue, 10 Jul 2001 10:32:01 -0400, "robm" <o...@here.org> wrote:

>try a SetLastError( 0 ) before the RegisterClass() and then
>GetLastError() after RegisterClass()
>i had a similar problem once, that was not detected only by
>the return from RegisterClass()
>
>i presume you are performing this inside your thread ?
>how do you create the thread ?
>
>BTW i plugged your code into a DLL thread where i have
>similar functionality that you describe and
>the code worked ?

This is really strange, because it worked for me some time as well but
suddenly stopped working, and I can't remember/recall what was changed
from the code to end it up not working. I've always been having
strange problems using more than one (modeless) window in application
with own window class (RegisterClass/CreateWindow).

>HTH
>rob

I use exported init function to set up the thread and message loop.
And yes, DefWindowProc gets properly called too in the msg procedure:
--------------------------------------------------------------------------------------------------------------------
__declspec(dllexport) int CommInit()
{
DWORD dwTmp;

g_hCommThread = CreateThread(NULL,
0,
CommThreadProc,
NULL,
0,
&dwTmp);

if(!g_hCommThread) return FALSE;

return TRUE;
}

DWORD CALLBACK CommThreadProc(void *p)
{
int rval;

//
// Initialize window
//
WNDCLASS wc;

wc.lpszClassName = "COMMCLS";
wc.lpfnWndProc = WindowProc;

wc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;


wc.hInstance = g_hInstDll;
wc.hIcon = (HICON) LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

// Create the main window now
rval = RegisterClass(&wc);

g_hWnd = CreateWindow("COMMCLS", "TestApp",
WS_OVERLAPPEDWINDOW,
0,
0,
200, 125,
NULL, NULL,
g_hInstDll,
NULL);

int error = GetLastError();

ShowWindow(g_hWnd, SW_SHOW);
UpdateWindow(g_hWnd);

MSG msg;

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

ExitThread(0);
return 0;
}

/**
* DLL entry point
*/
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID
lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstDll = (HINSTANCE) hModule;
break;

case DLL_PROCESS_DETACH:
g_hInstDll = NULL;
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

return TRUE;
}
--------------------------------------------------------------------------------------------------------------------

robm

unread,
Jul 11, 2001, 11:04:45 AM7/11/01
to
just for kicks....
could you try changing your (wc.lpszMenuName = NULL;) from
NULL to some non-NULL value

e.g. wc.lpszMenuName = "COMMCLSMENU" ;

and see if this has an affect ??

strangely enough i once had similar problems that you are
having, then i changed some of the "wc" fields and gave a
dummy men name and it started to work ??

hth
rob

xa...@usa.net wrote in message ...

rz

unread,
Jul 13, 2001, 2:32:55 PM7/13/01
to
You pass NULL as the first argument to LoadIcon. That means the call will
try to load the icon from the resources in the executable file, not the DLL.

Does the wndproc function get called at all? Perhaps it is not responding
correctly to some critical message.

I found my programs were _very_ sensitive to the way I set wc.hbrBackground.
Here is the relevant section of my code (I use the same function for all my
code, and dBox specifies whether I am registering the class for a dialog box
or a control):

(NOTE: My mailer will probably chop lines by the time you read this)
// Set background color
if (bDBox)
{
#if 0
// If this leaves parts of the dialog transparent, WndProc is not
calling DefDlgProc
// Causes failure under Win 95 (::RegisterClass returns 0, but so does
::GetLastError)
// Tested again 18 Jun 00
wc.hbrBackground = GetStockBrush( COLOR_WINDOW + 1 ); // Win32 macro
#elif 0
wc.hbrBackground = GetStockBrush( WHITE_BRUSH ); // Win32 macro
#else
// NOTE from Petter Hesselberg comp.os.ms-windows.programmer.win32
// 19 Oct 00: "... treating a system color index plus one as though
// it were a brush only work[s] in ..." certain contexts, such
// as registering a window class. Norman Bullen added that it might
// also be allowed in FillRect
// From Coder Infidel (17 March 00) and Daniel Fox (19 March 00)
// comp.os.ms-windows.programmer.win32
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
#endif
}
else
{
// PFI controls that actually use this function are really containers,
so they
// should be the background color
// COLOR_BTNFACE is used for control backbround (Petzold p. 375)
// Always add 1 to standard colors (Petzold, p. 375
// TODO: Find way to write run-time switch
#if 1
// 18 Jun 00
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND + 1);
// wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
#elif 0
// Under Win 95, this causes RegisterClass to fail??
// Tried again 18 Jun 00
wc.hbrBackground = GetStockBrush( COLOR_BTNFACE + 1 ); // Win32 macro
#elif 0
wc.hbrBackground = GetStockBrush( WHITE_BRUSH ); // Win32 macro
#else
// From Coder Infidel (17 March 00) and Daniel Fox (19 March 00)
// comp.os.ms-windows.programmer.win32
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1);
#endif
}

--
-----------------------------------------
To reply to me, remove the underscores (_) from my email address.

Robert E. Zaret
PenFact, Inc.
46 Beach Street
Boston, MA 02111
www.penfact.com

Vasanth Iyer

unread,
Aug 13, 2001, 4:57:06 PM8/13/01
to

I'm using CreateWindowEx which is of style popup so it will always succeed
as it is not a child window.

The sample is attached.

/***********************************************************************

FUNCTION:
InitInstance

PURPOSE:
Create and display the main window.

***********************************************************************/
BOOL InitInstance (HINSTANCE hInstance, int iCmdShow, LPVOID lpGlobals)
{


g_hwndMain = CreateWindowEx (
WS_EX_APPWINDOW,
g_szClassName, // Registered class name
g_szTitle, // Application window name
WS_SYSMENU|WS_CAPTION|WS_POPUP|WS_VISIBLE, // Window
style
300,
300,
300,
300,
NULL, // Handle to the parent window
NULL, // Menu Handle to the menu the identifier
hInstance, // Handle to the application instance
NULL); // Pointer to the window-creation data


// If it failed to create the window, return FALSE.
if (!g_hwndMain)
return FALSE;

ShowWindow (g_hwndMain, iCmdShow);
UpdateWindow (g_hwndMain);

SetTimer(g_hwndMain,100,1000*2,NULL);

return TRUE;
}

/***********************************************************************

FUNCTION:
InitApplication

PURPOSE:
Declare the window class structure, assign values to the window class
structure members, and register the window class.

***********************************************************************/
BOOL InitApplication (HINSTANCE hInstance)
{
WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hIcon = NULL;
wndclass.hInstance = hInstance;
wndclass.hCursor = NULL;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = g_szClassName;

return RegisterClass (&wndclass);
}

<xa...@usa.net> wrote in message
news:89clkt027r68bnvhb...@4ax.com...

0 new messages