FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need help for window creation

 
Post new topic   Reply to topic     Forum Index -> Visual D
View previous topic :: View next topic  
Author Message
flamaros



Joined: 02 Feb 2008
Posts: 33

PostPosted: Sat Sep 11, 2010 10:33 am    Post subject: Need help for window creation Reply with quote

Hi,

I am creating a little windowed application to learn D language and features.

I have some undefined structures and defines, that I don't know where to find.

Here is my code :
Code:

module engine.renderer.win32.mainWindow;

import std.c.windows.windows;
import std.c.stdio;
import std.string;
import std.exception;

import engine.maths.vector2d;
import engine.maths.vector3d;

extern (Windows)
{
   BOOL DestroyWindow(HWND hWnd);
   BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
   HWND GetDesktopWindow();
   LONG ChangeDisplaySettings(DEVMODE *lpDevMode, DWORD dwflags);
}

class MainWindowException : Exception
{
   enum   Error
   {
      WindowCreationFailed,
      FullScreenUnsupported,
      UnsupportedOption,
   }

   this(string message)
   {
      super(msg);
   }

   this(Error errNum, string msg)
   {
      string   text;
      switch (errNum)
      {
         case Error.WindowCreationFailed:
            text = "Window creation failed : " ~ msg;
            break;
         case Error.FullScreenUnsupported:
            text = "Swithcing to full screen mode failed : " ~ msg;
            break;
         case Error.UnsupportedOption:
            text = "An option is unsupported by your hardware or OS : " ~ msg;
            break;
         default:
            break;
      }
      super(text);      
   }
}

version (Windows)
{
   class MainWindow
   {
      this()
      {
         mhWnd = null;
      }
      
      ~this()
      {
         destroy();
      }

      void   destroy()
      {
         DestroyWindow(mhWnd);
         mhWnd = null;
      }

      void   create()
      {
         WNDCLASS   wc;

         currentWindow = this;

         //MSG         msg;
         HINSTANCE   hInstance = GetModuleHandleA(null);

         // register window class
         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
         wc.lpfnWndProc = &FrameWndProc;
         wc.cbClsExtra = 0;
         wc.cbWndExtra = 0;
         wc.hInstance = hInstance;
         wc.hIcon = LoadIconA(null, IDI_APPLICATION);
         wc.hCursor = LoadCursorA(null, IDC_ARROW);
         wc.hbrBackground = null;
         wc.lpszMenuName = null;
         wc.lpszClassName = toStringz(mName);
         
         if (!RegisterClassA(&wc))                  // Attempt To Register The Window Class
            throw new MainWindowException(MainWindowException.Error.WindowCreationFailed, "Registering the window class failed.");

         ShowCursor(FALSE);   // Hide Mouse Pointer (not correctly supported on seven due to GDI)

         if (fullScreen())
         {
            DWORD      dwExStyle;            // Window Extended Style
            DWORD      dwStyle;            // Window Style
            RECT      WindowRect;            // Grabs Rectangle Upper Left / Lower Right Values
            DEVMODE      dmScreenSettings;      // Device Mode

            dwExStyle         = WS_EX_APPWINDOW | WS_EX_TOPMOST;         // Window Extended Style
            dwStyle            = WS_POPUP | WS_VISIBLE;               // Windows Style
            WindowRect.left      = 0;                              // Set Left Value To 0
            WindowRect.right   = cast(int)(size().x);                  // Set Right Value To Requested Width
            WindowRect.top      = 0;                              // Set Top Value To 0
            WindowRect.bottom   = cast(int)(size().y);                  // Set Bottom Value To Requested Height
            ShowCursor(FALSE);                                    // Hide Mouse Pointer
            AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);      // Adjust Window To True Requested Size
            mhWnd = CreateWindowA(toStringz(mName), toStringz(mName),
                            dwStyle,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,
                            null, null, hInstance, null);

//            memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));         // Makes Sure Memory's Cleared
            dmScreenSettings.dmSize         = dmScreenSettings.sizeof;      // Size Of The Devmode Structure
            dmScreenSettings.dmPelsWidth   = size().x;                  // Selected Screen Width
            dmScreenSettings.dmPelsHeight   = size().y;                  // Selected Screen Height
            //dmScreenSettings.dmBitsPerPel   = 32;                     // Selected Bits Per Pixel
            dmScreenSettings.dmFields      = /*DM_BITSPERPEL |*/ DM_PELSWIDTH | DM_PELSHEIGHT;
            // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
            if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
            {
               // Devrait quand meme creer la fenetre sans le fullscree, voir avec scope(failed)
               scope(failure) fullScreen(false);
               throw new MainWindowException(MainWindowException.Error.FullScreenUnsupported, "Full screen isn't supported by your video card.");
               //MessageBoxA(null, "The Fullscreen Mode Is Not Supported By\nYour Video Card.", "TeEngine", MB_ICONEXCLAMATION);
            }
         }
         else
         {
            DWORD      dwExStyle;            // Window Extended Style
            DWORD      dwStyle;            // Window Style
            RECT      WindowRect;            // Grabs Rectangle Upper Left / Lower Right Values
         
            dwExStyle   = WS_EX_APPWINDOW;      // Window Extended Style
      //      dwStyle      = WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE;                                    // Windows Style
            dwStyle      = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;   // Windows Style
            WindowRect.left      = 0;         // Set Left Value To 0
            WindowRect.right   = cast(int)(size().x);      // Set Right Value To Requested Width
            WindowRect.top      = 0;         // Set Top Value To 0
            WindowRect.bottom   = cast(int)(size().y);      // Set Bottom Value To Requested Height
            AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);   // Adjust Window To True Requested Size
            mhWnd = CreateWindowA(toStringz(mName), toStringz(mName),
                            dwStyle,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,
                            null, null, hInstance, null);
      //      setSize(mSize);
         }

         ShowWindow(mhWnd, SW_SHOW);
         SetForegroundWindow(mhWnd);
         SetFocus(mhWnd);

         if (!mhWnd)
            throw new MainWindowException(MainWindowException.Error.WindowCreationFailed, "Resulting window handle is invalid.");
//         initCamera();   // To add
      }

      @property
      {
         void   fullScreen(bool flag) {mFullScreen = flag;}
         bool   fullScreen() {return mFullScreen;}
         
         void   size(const ref Vector3d!(float) size)
         {
//            updateCamera(size);   // To add
//            MainWindowLayout.setSize(size);   // To add
            mSize = size;   // To remove
            
            if (!mhWnd)
               return;

            RECT   rcClient, rcWindow;
            POINT   ptDiff;

            GetClientRect(mhWnd, &rcClient);
            GetWindowRect(mhWnd, &rcWindow);
            ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
            ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
            MoveWindow(mhWnd, rcWindow.left, rcWindow.top, cast(int)(this.size().x) + ptDiff.x, cast(int)(this.size().y) + ptDiff.y, true);
         }
         Vector3d!(float)   size() {return mSize;}
      }
      
      void   updateEvents()
      {
         MSG      msg;

         currentWindow = this;
         if (PeekMessageA(&msg, mhWnd, 0, 0, PM_REMOVE))
         {
            // handle or dispatch messages
            TranslateMessage(&msg);
            DispatchMessageA(&msg);
         }
      }

      Vector2d!(int)   screenResolution()
      {
         RECT   rc;

         GetWindowRect(GetDesktopWindow(), &rc);
         return Vector2d!(int)(rc.right - rc.left, rc.bottom - rc.top);
      }

      bool   setName(const ref string name)
      {
         if (!name.GetLength())   // Window creation will failed
            return false;
         mName = name;
         if (!mhWnd)   // It's not an error, the name will be set with the window creation
            return true;
         return SetWindowText(mhWnd, mName.c_str()) > 0;
      }
      
   private:
      HWND   mhWnd;
      bool   mFullScreen;

      // To delete (with inheritance of layouts)
      string            mName;
      Vector3d!(float)   mSize;
   }

   MainWindow   currentWindow;

   int   FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
      //   RECT                  rect;
      //   KeyEvent               keyEvent;
      //   MouseEvent               mouseEvent;

      POINTS         pos;
      RECT         rect;
      Vector2d!(int)   size;

      switch (message)
      {
      case WM_CREATE:
         return 0;
      case WM_MOVE:
         currentWindow.mPosition.x = LOWORD(lParam);
         currentWindow.mPosition.y = HIWORD(lParam);
         return 0;
      case WM_MOVING:
         rect = lParam[0];
         currentWindow.mPosition.x = rect.left;
         currentWindow.mPosition.y = rect.top;
         return 0;
      case WM_SIZE:
         size.x = LOWORD(lParam);
         size.y = HIWORD(lParam);
         currentWindow.setSize(TeVector3f32(size.x, size.y, 0.0f));
         return 0;
      case WM_PAINT:
         refreshRender();
         return 0;
      case WM_DESTROY:
         currentWindow.mCloseRequested = true;
         return 0;
      case WM_MOUSEMOVE:
         currentWindow.mMousePreviousPosition = currentWindow.mMousePosition;
         pos = MAKEPOINTS(lParam);
         currentWindow.mMousePosition.x = pos.x;
         currentWindow.mMousePosition.y = pos.y;
         return 0;
      case WM_LBUTTONDOWN:
         currentWindow.mMousePreviousButton = currentWindow.mMouseButton;
         currentWindow.mMouseButton |= MainWindowLayout.Left;
         //TePrintf("[FrameWndProc] %x\n", currentWindow.mMouseButton);
         return 0;
      case WM_LBUTTONUP:
         currentWindow.mMousePreviousButton = currentWindow.mMouseButton;
         currentWindow.mMouseButton &= ~MainWindowLayout.Left;
         //TePrintf("[FrameWndProc] %x\n", currentWindow.mMouseButton);
         return 0;
      case WM_RBUTTONDOWN:
         currentWindow.mMousePreviousButton = currentWindow.mMouseButton;
         currentWindow.mMouseButton |= MainWindowLayout.Right;
         //TePrintf("[FrameWndProc] %x\n", currentWindow.mMouseButton);
         return 0;
      case WM_RBUTTONUP:
         currentWindow.mMousePreviousButton = currentWindow.mMouseButton;
         currentWindow.mMouseButton &= ~MainWindowLayout.Right;
         //TePrintf("[FrameWndProc] %x\n", currentWindow.mMouseButton);
         return 0;


         /*      mouseEvent.type = Move;
         mouseEvent.previousPosition = mouseEvent.position;
         pos = MAKEPOINTS(lParam);
         mouseEvent.position.x = pos.x;
         mouseEvent.position.y = pos.y;
         inputManager.SendMouseEvent(mouseEvent);


         // Partie a supprimer
         GetWindowRect(hWnd, &rect);


         pos.x += (SHORT)rect.left;         // because mouse position is relative to the window
         pos.y += (SHORT)rect.top;         // they must be relatives to the screen
         if (wParam == MK_LBUTTON)
         {
         MoveWindow(hWnd,
         rect.left + pos.x - prevPos.x, rect.top + pos.y - prevPos.y,
         rect.right - rect.left, rect.bottom - rect.top, TRUE);
         }
         prevPos = pos;
         return 0;

         case WM_LBUTTONDOWN:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::Left;
         mouseEvent.state = Down;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         case WM_LBUTTONUP:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::Left;
         mouseEvent.state = Up;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         //   case WM_LBUTTONDBLCLK:
         case WM_RBUTTONDOWN:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::Right;
         mouseEvent.state = Down;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         case WM_RBUTTONUP:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::Right;
         mouseEvent.state = Up;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         //   case WM_RBUTTONDBLCLK:
         case WM_MBUTTONDOWN:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::WheelDown;
         mouseEvent.state = Down;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         case WM_MBUTTONUP:
         mouseEvent.type = Button;
         mouseEvent.button = MouseButton::WheelDown;
         mouseEvent.state = Up;
         inputManager.SendMouseEvent(mouseEvent);
         return 0;
         //   case WM_MBUTTONDBLCLK:
         //   case WM_MOUSEWHEEL:

         case WM_KEYDOWN:
         case WM_KEYUP:
         keyEvent.key = Key::UnknownKey;
         keyEvent.state = (PhyBtnSte)(Down + (message - WM_KEYDOWN));
         switch (wParam)
         {
         case 'A':
         case 'B':
         case 'C':
         case 'D':
         case 'E':
         case 'F':
         case 'G':
         case 'H':
         case 'I':
         case 'J':
         case 'K':
         case 'L':
         case 'M':
         case 'N':
         case 'O':
         case 'P':
         case 'Q':
         case 'R':
         case 'S':
         case 'T':
         case 'U':
         case 'V':
         case 'W':
         case 'X':
         case 'Y':
         case 'Z':
         keyEvent.key = (Key::KeysStroke)(Key::KeyA + (wParam - 'A'));
         break;

         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         keyEvent.key = (Key::KeysStroke)(Key::Key0 + (wParam - '0'));
         break;

         case VK_F1:
         case VK_F2:
         case VK_F3:
         case VK_F4:
         case VK_F5:
         case VK_F6:
         case VK_F7:
         case VK_F8:
         case VK_F9:
         case VK_F10:
         case VK_F11:
         case VK_F12:
         keyEvent.key = (Key::KeysStroke)(Key::KeyF1 + (wParam - VK_F1));
         break;

         case VK_ESCAPE:
         keyEvent.key = Key::KeyEscape;
         break;
         }
         if (keyEvent.key != Key::UnknownKey)
         inputManager.SendKeyEvent(keyEvent);
         return 0;
         */
      default:
         return DefWindowProc(hWnd, message, wParam, lParam);
      }
   }
}


And here my errors :

Code:

..\Sources\engine\renderer\win32\mainWindow.d(104): Error: DEVMODE is used as a type
..\Sources\engine\renderer\win32\mainWindow.d(106): Error: undefined identifier WS_EX_APPWINDOW
..\Sources\engine\renderer\win32\mainWindow.d(106): Error: undefined identifier WS_EX_TOPMOST
..\Sources\engine\renderer\win32\mainWindow.d(125): Error: undefined identifier DM_PELSWIDTH
..\Sources\engine\renderer\win32\mainWindow.d(125): Error: undefined identifier DM_PELSHEIGHT
..\Sources\engine\renderer\win32\mainWindow.d(127): Error: undefined identifier CDS_FULLSCREEN
..\Sources\engine\renderer\win32\mainWindow.d(127): Error: undefined identifier DISP_CHANGE_SUCCESSFUL
..\Sources\engine\renderer\win32\mainWindow.d(141): Error: undefined identifier WS_EX_APPWINDOW


I had tough to copy definitions directly in my D file, but I don't find this clean.

I am also interested by any advice.
Back to top
View user's profile Send private message
sagitario



Joined: 03 Mar 2007
Posts: 292

PostPosted: Sun Sep 12, 2010 11:50 pm    Post subject: Reply with quote

Hi,

the definitions in the std.c.windows.windows are incomplete, especially for GUI related stuff, so no wonder you are hitting missing definitions now and then. As far as I know the options are:

- create your own module with the missing declarations converted from the windows SDK header files and import it where needed
- try the work of some other projects like core32 (http://www.dsource.org/projects/core32) that target translation of the full windows API to D
- use the machine translated files created when compiling Visual D. See the build instructions (http://www.dsource.org/projects/visuald/wiki/Build_from_source) for more details. The latest svn revision also works with the v7.1 windows SDK. (You'll find the converted files in sdk/win32. It does not convert the complete SDK, just 40+ files that I found essential.)

An issue with the last approach is that you cannot easily mix with imports from std.c.windows.windows because you might get ambiguities.

Rainer
Back to top
View user's profile Send private message
flamaros



Joined: 02 Feb 2008
Posts: 33

PostPosted: Tue Sep 14, 2010 5:08 pm    Post subject: Reply with quote

hi,

Thx for tips, I had a module to declare missing structure and defines I use. It allow to build the project correctly.

I may be interested by projects like Core32 that give us a chance of using wide version of win32 API.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Visual D All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group