View previous topic :: View next topic |
Author |
Message |
flamaros
Joined: 02 Feb 2008 Posts: 33
|
Posted: Sat Sep 11, 2010 10:33 am Post subject: Need help for window creation |
|
|
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 |
|
|
sagitario
Joined: 03 Mar 2007 Posts: 292
|
Posted: Sun Sep 12, 2010 11:50 pm Post subject: |
|
|
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 |
|
|
flamaros
Joined: 02 Feb 2008 Posts: 33
|
Posted: Tue Sep 14, 2010 5:08 pm Post subject: |
|
|
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 |
|
|
|
|
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
|