www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Win32 RegisterClass Error

reply GaboonViper <gaboonviper gmx.net> writes:
Hi,

I've been working with win32 libraries for a few weeks. I'm trying to  =

build a GUI framework, as I'm not satisfied with the ones currently  =

available.

So currently I'm working on detecting win32 errors and I've found that  =

RegisterClass is giving me an Error Code 2, which apparently translates =
to  =

"The system cannot find the file specified".

It doesn't really seem to matter what I change. It always gives me the  =

same problem. I'm using the win32 headers from the bindings project on  =

dsource.org. However I tried the std.c.windows.windows with the same  =

results.

Below is the code that reproduces the problem. It's basically a slice of=
  =

one of the tutorials on dsource.org.

Can anyone tell me what causes this error? And how to fix it?

Boyd.




module main;

import std.string;
import std.c.windows.windows;

static HINSTANCE ghInstance;
static HWND      ghWndMain;

void Win32ErrorCheck(char[] aFunction, char[] aFile, int aLine){
     int fLastError =3D GetLastError();
     if (fLastError > 0){
         char[256] fMessage;
         /*FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
             null, fLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)=
,  =

fMessage.ptr, 256, null );*/

         throw new Exception(aFile~ "("~toString(aLine)~"): Win32 Error =
 =

"~toString(fLastError)~" for " ~ aFunction ~ ", ");
     } else {
         //ShowMessage(aFunction ~ " succeeded");
     }
}

void DoMessagePump()
{
   MSG msg;
   while (GetMessageA(&msg, cast(HWND) null, 0, 0)) {
     TranslateMessage(&msg);
     DispatchMessageA(&msg);
   }
}

void CreateMainWindow()
{
   HWND hWnd;
   hWnd =3D CreateWindowA("DWndClass",
                "MiniCalc",
                WS_THICKFRAME | WS_MAXIMIZEBOX
                | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE,
                CW_USEDEFAULT, CW_USEDEFAULT,
                125, 150, HWND_DESKTOP,
                cast(HMENU) null, ghInstance, null);
   assert(hWnd);
   ghWndMain =3D hWnd;
}

void InitApplication()
{
   WNDCLASS wc;
   wc.lpszClassName =3D "DWndClass";
   wc.style =3D CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc =3D &WindowProc;
   wc.hInstance =3D ghInstance;
   wc.hIcon =3D LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION);
   wc.hCursor =3D LoadCursorA(cast(HINSTANCE) null, IDC_CROSS);
   wc.hbrBackground =3D cast(HBRUSH) (COLOR_WINDOW + 1);
   wc.lpszMenuName =3D null;
   wc.cbClsExtra =3D wc.cbWndExtra =3D 0;

   assert(RegisterClassA(&wc));
   Win32ErrorCheck("RegisterClassA", __FILE__, __LINE__);
}

void InitInstance()
{
   ghInstance =3D GetModuleHandleA(null);
   InitApplication();

   CreateMainWindow();
}

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

/* Note the similarity of this code to the console D startup
  * code in \dmd\src\phobos\dmain2.d
  * You'll also need a .def file with at least the following in it:
  *  EXETYPE NT
  *  SUBSYSTEM WINDOWS
  */

extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleUnitTests();

extern (Windows)
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
             LPSTR lpCmdLine, int nCmdShow)
{
   int result =3D 1;

   gc_init();      // initialize garbage collector
   _minit();     // initialize module constructor table

   try {
     _moduleCtor();    // call module constructors
     _moduleUnitTests(); // run unit tests (optional)

     InitInstance();
     DoMessagePump();
   }
   catch (Object o) {    // catch any uncaught exceptions
     MessageBoxA(null, cast(char *)o.toString(), "Error",
                 MB_OK | MB_ICONEXCLAMATION);
     result =3D 0;   // failed
   }
   gc_term();      // run finalizers; terminate garbage collector
   return result;
}

extern(Windows)
int WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
{
   switch (uMsg) {

     case WM_DESTROY:
       PostQuitMessage(0);
       break;

     case WM_NOTIFY:
       break;

     default:
       break;
   }
   return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
Nov 17 2007
next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
GaboonViper wrote:
 Hi,
 
 I've been working with win32 libraries for a few weeks. I'm trying to 
 build a GUI framework, as I'm not satisfied with the ones currently 
 available.
 
 So currently I'm working on detecting win32 errors and I've found that 
 RegisterClass is giving me an Error Code 2, which apparently translates 
 to "The system cannot find the file specified".
 
 It doesn't really seem to matter what I change. It always gives me the 
 same problem. I'm using the win32 headers from the bindings project on 
 dsource.org. However I tried the std.c.windows.windows with the same 
 results.
 
 Below is the code that reproduces the problem. It's basically a slice of 
 one of the tutorials on dsource.org.
 
 Can anyone tell me what causes this error? And how to fix it?
 
 Boyd.

The problem is that there is no problem. If you check the return value of RegisterClass, you'll see that it works fine. The reason you get this error from GetLastError, is because the last error is only defined when an error actually occured. It doesn't tell you if a function executed succesfully. A note about the message pump from msdn: <quote> Warning Because the return value can be nonzero, zero, or -1, avoid code like this: while (GetMessage( lpMsg, hWnd, 0, 0)) ... The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this: BOOL bRet; while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } } </quote>
Nov 17 2007
parent GaboonViper <gaboonviper gmx.net> writes:
Of course!

Thanks, this stupid problem had my brain whacked for hours:/ Sometimes  =

it's the obvious that we can't figure out.

As for the messagepump thing. I'm not actually using the code I posted, =
 =

except to figure out that one problem. I don't handle messages with a  =

result <=3D 0. Though I don't actually raise an error message either, so=
 I'm  =

glad for this reminder.

Thanks again,
Boyd.

---------
On Sat, 17 Nov 2007 13:31:13 +0100, Lutger <lutger.blijdestijn gmail.com=
  =

wrote:
 GaboonViper wrote:
 Hi,
  I've been working with win32 libraries for a few weeks. I'm trying t=


 build a GUI framework, as I'm not satisfied with the ones currently  =


 available.
  So currently I'm working on detecting win32 errors and I've found th=


 RegisterClass is giving me an Error Code 2, which apparently translat=


 to "The system cannot find the file specified".
  It doesn't really seem to matter what I change. It always gives me t=


 same problem. I'm using the win32 headers from the bindings project o=


 dsource.org. However I tried the std.c.windows.windows with the same =


 results.
  Below is the code that reproduces the problem. It's basically a slic=


 of one of the tutorials on dsource.org.
  Can anyone tell me what causes this error? And how to fix it?
  Boyd.

The problem is that there is no problem. If you check the return value=

 of RegisterClass, you'll see that it works fine. The reason you get th=

 error from GetLastError, is because the last error is only defined whe=

 an error actually occured. It doesn't tell you if a function executed =

 succesfully.


 A note about the message pump from msdn:

 <quote>

 Warning

 Because the return value can be nonzero, zero, or -1, avoid code like =

 this:

 while (GetMessage( lpMsg, hWnd, 0, 0)) ...

 The possibility of a -1 return value means that such code can lead to =

 fatal application errors. Instead, use code like this:

 BOOL bRet;

 while( (bRet =3D GetMessage( &msg, hWnd, 0, 0 )) !=3D 0)
 {
      if (bRet =3D=3D -1)
      {
          // handle the error and possibly exit
      }
      else
      {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
 }

 </quote>

Nov 17 2007
prev sibling parent "Stewart Gordon" <smjg_1998 yahoo.com> writes:
"GaboonViper" <gaboonviper gmx.net> wrote in message 
news:op.t1xpyxi8th8wtu gabonica.home.nl...
<snip>
 void InitApplication()
 {
    WNDCLASS wc;
    wc.lpszClassName = "DWndClass";
    wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = &WindowProc;
    wc.hInstance = ghInstance;
    wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION);
    wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS);
    wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1);
    wc.lpszMenuName = null;
    wc.cbClsExtra = wc.cbWndExtra = 0;

    assert(RegisterClassA(&wc));

Your code is broken here. If compiling in release mode, assert expressions are not evaluated, and so your window class won't be registered. Moreover, because RegisterClass (like many Windows API functions) returns zero on failure, the failure of the assert would render the following statement useless:
    Win32ErrorCheck("RegisterClassA", __FILE__, __LINE__);
 }

Simplest fix: if (!RegisterClassA(&wc)) { Win32ErrorCheck("RegisterClassA", __FILE__, __LINE__); } Stewart. -- My e-mail address is valid but not my primary mailbox. Please keep replies on the 'group where everybody may benefit.
Nov 18 2007