(C++) Basic Win32 Window

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Dances
Posts: 454
Joined: Sat Jul 02, 2005 1:45 am
Location: Canada
Contact:

(C++) Basic Win32 Window

Post by Dances »

Heres the code to create a basic Win32 Window without the extra junk from the tutorial. I also pointed out an issue not mentioned in the tutorial in my code.

Code: Select all

//DO NOT support XP themes. You will break your window

#include <irrlicht.h> 
#include <windows.h> 

using namespace irr; 
using namespace video; 

//It seems the event receiver doesn't like being in a Win32 Window so
//our window processor will have to take care of keyboard input

IrrlichtDevice* device;
IVideoDriver* driver;
bool akey = false; //boolean for the 'a' key

static LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
   switch (message) 
   { 
   case WM_CLOSE:
        device->closeDevice(); 
        device->drop(); 
        exit(0);
        break;
   case WM_KEYDOWN:
        switch(wParam)
        {
           case VK_ESCAPE: //virtual key escape
                device->closeDevice();
                device->drop();
                exit(0);
                break;
           case 0x41: //'a' key hexadecimal
                if(lParam >> 31 == 0x0) //if the key was not pressed beforehand
                   akey = true;
                break;
           default:
                akey = false;
                break;
        }
        break;
   case WM_KEYUP:
        switch(wParam)
        {
          case 0x41: //'a' key hexadecimal
               if(lParam >> 31 != 0x0) //if the key was pressed beforehand
                  akey = false;
               break;
        }
        break;
   case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
      break;
   } 

   return DefWindowProc(hWnd, message, wParam, lParam); 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hpre, LPSTR cmd, int cc) 
{ 

   const char* Win32ClassName = "CIrrlichtWindowsBase"; 

   WNDCLASSEX wcex; 
   wcex.cbSize         = sizeof(WNDCLASSEX); 
   wcex.style         = 0; 
   wcex.lpfnWndProc   = CustomWndProc; 
   wcex.cbClsExtra      = 0; 
   wcex.cbWndExtra      = 0; 
   wcex.hInstance      = hInstance; 
   wcex.hIcon         = 0; 
   wcex.hCursor      = 0; 
   wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW); 
   wcex.lpszMenuName   = 0; 
   wcex.lpszClassName   = Win32ClassName; 
   wcex.hIconSm      = 0; 

   RegisterClassEx(&wcex); 

   HWND hWnd = CreateWindow( Win32ClassName, "Win32Base", 
      WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 
      NULL, NULL, hInstance, NULL); 
      
   //Put your resolution in the code above where 640, 480 is. The window is NOT resizeable

   HWND hIrrlichtWindow = CreateWindow("BUTTON", "", WS_CHILD | WS_VISIBLE, 
         0, 0, 640, 480, hWnd, NULL, hInstance, NULL); 
         
   //Make sure you echo your resolution here (unless you want blank spaces around your
   //renders). Do NOT change anything else or you'll break your window
         
   SIrrlichtCreationParameters param; 
   param.WindowId = reinterpret_cast<s32>(hIrrlichtWindow); 
   param.DriverType = EDT_DIRECT3D9; 
   
   device = createDeviceEx(param);
   driver = device->getVideoDriver();

   ShowWindow(hWnd , SW_SHOW); 
   
   device->sleep(300); //If we don't wait just a little bit the program will have a hard
   //time showing up on the taskbar

   while(device->run())
   {
      if(GetActiveWindow() == hWnd)
      {
         SetFocus(hWnd);
         //this line seems pointless, but without it your program will refuse to 
         //take input at first until the window is deactivated and activated again
         EnableWindow(hIrrlichtWindow, true);
         if (akey)
            printf("a key was pressed ");
         driver->beginScene(true, true, 0); 
         driver->endScene(); 
      }
      else
         device->sleep(200); //This will give the user a little bit more CPU while
         //multitasking with our program
   }
   device->closeDevice(); 
   device->drop(); 
   return 0; 
}
Hope it helps someone from the headache this was for me XD.

EDIT: isWindowActive is broken (I think because of createDeviceEx), so I have added an if statement to stop rendering if the window is not active using a windows function.

EDIT 2:I've noticed some event receiver problems with this. It seems when the window loses focus the keyboard will not respond anymore. This means you need to use the wnd proc for keyboard receiveing. I have altered the main loop and added some example processing code. You can still do all your mouse and GUI stuff with an Event Receiver.

If you need more hex keycodes or virtual key names try here: http://delphi.about.com/od/objectpascalide/l/blvkc.htm

EDIT 3:I've worked on the key input a bit more. The way it was coded it responded with the key repeat rate. Now it will work as long as the key is pressed down. processing of the event is now in the main loop.

EDIT 4:I've noticed sometimes the program has a hard time showing up on the taskbar. I added a sleep call to give it a chance to get on there so you aren't running a game without a task bar icon ^.^ I also added a sleep statement when the window isn't active so that a multitasker wont have all their processor power taken up by an empty loop!
Last edited by Dances on Fri Jun 01, 2007 4:34 pm, edited 11 times in total.
oldskoolPunk
Posts: 199
Joined: Wed Nov 29, 2006 4:07 am

Post by oldskoolPunk »

Thank you Dances for this simplified example. You hard work and headaches are very much appreciated :)
Signature? I ain't signin nuthin!
Dances
Posts: 454
Joined: Sat Jul 02, 2005 1:45 am
Location: Canada
Contact:

Post by Dances »

Thanks for the compliment! I've noticed a problem with event receivers and updated this code so you might want to have another read through!
RoBaTte
Posts: 10
Joined: Thu Jun 07, 2007 2:34 pm

Als Desktop-Hintergrund...

Post by RoBaTte »

Hi Dances,

I used your code and it worked fine. Thanks.
But then I used FindWindow( 0, "Program Manager"); as parent for my application, just for using my irrlicht-app as desktopwallpaper.
Everything works fine and uses nearly no cpu, but I can't get any usefull messages/events.
Do you have any idea, what to do?

Thanks and greetings.
Dances
Posts: 454
Joined: Sat Jul 02, 2005 1:45 am
Location: Canada
Contact:

Re: Als Desktop-Hintergrund...

Post by Dances »

This probably doesn't sound very good but I don't really know Windows programming all that well. I have never used the FindWindow function. I am guessing that something in your code is taking focus away from the Irrlicht window. Play with functions like EnableWindow, SetActiveWindow, and SetFocus for both hWnd and hIrrlichtWindow and you might manage to get control back.

If you need to find out what window is active things like GetFocus can help you with that.

I'm really not sure, though. Most of my code was trial and error.
Post Reply