Im making a game with a custom game engine and when you have selected the window that it creates it doesn't allow you to use media keys e.g. changing volume or playing/pausing music or anything that has to do with windows like getting the windows start menu and alt+tab behaves weird
It feels like my window is "blocking" all system specific keys and commands
The code is written in c++
Heres the code i'm using for creating the window:
bool FrameWork::CreateDXWnd(int x, int y, int width, int height)
{
HWND hwnd;
WNDCLASSEX wc;
m_hInstance = GetModuleHandle(nullptr);
//setup window class with default setings:
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hInstance;
//wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
wc.hIcon = (HICON)LoadImage(m_hInstance, ".\\Assets\\Icons\\NgineIcon512.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(nullptr, IDC_HAND);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = nullptr;
wc.lpszClassName = applicationName.c_str();
wc.cbSize = sizeof(WNDCLASSEX);
if (!RegisterClassEx(&wc))
{
Error(1);
return false;
}
//Style of window
//int nStyle = WS_OVERLAPPED | WS_SYSMENU | WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX;
int nStyle = WS_OVERLAPPED | WS_SYSMENU | WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX;
SettingsManager::GetInstance()->SetNativeResolution(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
if (SettingsManager::GetInstance()->GetDisplayMode() == FULLSCREEN)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)SettingsManager::GetInstance()->GetScreenWidth();
dmScreenSettings.dmPelsHeight = (unsigned long)SettingsManager::GetInstance()->GetScreenHeight();
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
else
{
}
if ((SettingsManager::GetInstance()->GetDisplayMode() == BORDERLESS))
{
hwnd = CreateWindowEx(WS_EX_APPWINDOW, applicationName.c_str(), applicationName.c_str(), WS_POPUP, x, y, SettingsManager::GetInstance()->GetScreenWidth(), SettingsManager::GetInstance()->GetScreenHeight(), nullptr, nullptr, m_hInstance, nullptr);
}
else
{
hwnd = CreateWindowEx(WS_EX_APPWINDOW, applicationName.c_str(), applicationName.c_str(), nStyle, x, y, SettingsManager::GetInstance()->GetScreenWidth(), SettingsManager::GetInstance()->GetScreenHeight(), nullptr, nullptr, m_hInstance, nullptr);
}
if (hwnd == nullptr)
{
Error(2);
Ngine::GetInstance()->Release();
PostQuitMessage(0);
return false;
}
if (!Ngine::GetInstance()->InitGraphics(hwnd))
{
Error(hwnd, 30);
Ngine::GetInstance()->Release();
PostQuitMessage(0);
UnregisterClass(applicationName.c_str(), m_hInstance);
m_hInstance = nullptr;
DestroyWindow(hwnd);
return false;
}
Ngine::GetInstance()->GetGraphics()->SetHwnd(hwnd);
ShowWindow(hwnd, SW_SHOW);
SetForegroundWindow(hwnd);
SetFocus(hwnd);
return true;
}
Tim. The code you are showing deals with creating a window, not with how to handle the input to the window. To handle input, you need to set up a Message handling loop in your code.
Typically, in a game engine, you will have a main loop or "Game Loop", with each pass through the loop typically resulting in a single frame drawn. The first thing the Game Loop does is handle window messages. This allows you to handle the typical windows functions. Then, once you have no more messages to deal with, you will move on to handling your game's logic and rendering.
I recommend you take a look at Braynzarsoft's tutorials. The tutorial I linked deals with setting up your window and how to make a bare-bones Windows Message system.
Once you understand the basics of that, you can refine your post if needed to get more information.
Related
I am currently working on a project, where i need to create transparent bubble as main body. To make this transparence i used WS_EX_LAYERED on window creation. But now, i can't get children to render, but they do exist and even function like they should, they are just not visible. Without Layered Window mode everything renders just fine. What is wrong?
Here is my window creation:
winClass = {};
winClass.lpfnWndProc = WindowProc;
winClass.hInstance = hInstance;
winClass.hIcon = hIcon;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.lpszClassName = CLASS_NAME;
winClass.hbrBackground = (HBRUSH)0;
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClass(&winClass);
Gdiplus::GdiplusStartupInput gdiinput = {};
gdiinput.GdiplusVersion = 1;
Gdiplus::GdiplusStartupOutput gdioutput = {};
Gdiplus::GdiplusStartup(&WinGDIToken, &gdiinput, &gdioutput);
hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_LAYERED,
CLASS_NAME, // Window class
L"Color Picker", // Window text
WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, 700 * Scale, 516 * Scale,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
Window::PopulateClientWithWindows(hWnd);
And here is PopulateClientWithWindows(hwnd) func:
void Window::PopulateClientWithWindows(HWND hwnd)
{
HWND test = CreateWindow(L"edit", L"Test ", WS_VISIBLE | WS_CHILD , 50, 50,
100, 100, hwnd, NULL, hI, NULL);
}
When I create a window with CreateWindowEx it will follow the resolution but also use the scale settings from the display settings. So, in 1920 x 1080 if I try to create the window, the size is actually 1200 something when scale is at 150%. Is there a way to get around this limitation? If I just set the size manually to 1920 x 1080 I get a cropped window. Thanks.
auto activeWindow = GetActiveWindow();
HMONITOR monitor = MonitorFromWindow(activeWindow, MONITOR_DEFAULTTONEAREST);
//
// Get the logical width and height of the monitor
MONITORINFOEX monitorInfoEx;
monitorInfoEx.cbSize = sizeof(monitorInfoEx);
GetMonitorInfo(monitor, &monitorInfoEx);
auto cxLogical = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left;
auto cyLogical = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top;
vScreenSize = { cxLogical, cyLogical };
WNDCLASS wc;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.hInstance = GetModuleHandle(nullptr);
wc.lpfnWndProc = olc_WindowEvent;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszMenuName = nullptr;
wc.hbrBackground = nullptr;
wc.lpszClassName = olcT("Wusik SQ480 Engine");
RegisterClass(&wc);
DWORD dwExStyle = 0;
DWORD dwStyle = WS_VISIBLE | WS_POPUP;
olc::vi2d vTopLeft = vWindowPos;
// Keep client size as requested
RECT rWndRect = { 0, 0, vWindowSize.x, vWindowSize.y };
AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
int width = rWndRect.right - rWndRect.left;
int height = rWndRect.bottom - rWndRect.top;
olc_hWnd = CreateWindowEx(dwExStyle, olcT("Wusik SQ480 Engine"), olcT(""), dwStyle,
vTopLeft.x, vTopLeft.y, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
Thanks to Remy Lebeau it was as simple as adding the following call to the main initialization of the app. Now I always get a window with the physical resolution and not a logic scaled resolution.
SetProcessDPIAware();
I am writing a C/C++ windows app which calls CreateWindow as follows:
HWND hWnd = CreateWindow(pszClassName, title_.c_str(), WS_OVERLAPPED | WS_VISIBLE | WS_POPUP | WS_SIZEBOX, 50, 50, 400, 100, NULL, NULL, hInst, this);
Nothing particularly complex about it, however, it is appearing on every desktop on my computer when I switch from one desktop to another with CTRL-WIN < or >.
How do you make window you create in an app remain only on the desktop that you created it on?
I am compiling this app in 64bit and running it on Windows 10.
Code:
Global:
WNDCLASSEX wc;
Window procedure:
case WM_KEYDOWN:
if(wParam == VK_F11)
{
wc.style = HWND_DESKTOP;//The window is child
//of desktop
}
break;
WinMain:
LPCSTR windowName = "Answer on StackOwerflow";
MSG messages;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "The classname";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
wc.lpszClassName,
windowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd);
UpdateWindow(hWnd);
while(GetMessage(&messages, NULL, 0, 0) > 0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return 0;
I'm trying to create a simple OpenGL context but the program crashes on ChoosePixelFormat with the error "Unhandled exception at 0x779CE0E6 (ntdll.dll) in OpenGL.exe: 0xC0000005: Access violation reading location 0x00000044." This same code used to work a while back but for some reason doesn't work anymore. I tried updating my graphics drivers to no avail. If it matters, I have a 64-bit Windows 7 Home premium, a GeForce 570 and a Intel Core i7-2600 3,40 GHz.
This is the code I use in the order of execution to the point it crashes:
GLEngine gl(WndProc); //WndProc just calls DefWindowProc
- calls ->
GLEngine::GLEngine(WNDPROC wndproc) { //Initialize class
hRC = NULL;
hDC = NULL;
hWnd = NULL;
fullscreen = false;
active = false;
proc = wndproc;
itemsLength = 0;
currentActive = this;
success = true;
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) {
gl.CreateGL2Window("Test", 1300, 900, 8, false, true);
- calls ->
bool GLEngine::CreateGL2Window(char* title, int width, int height, bool internalflag) {
GLuint pixelFormat;
WNDCLASSEX wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT windowRect;
windowRect.left = (long)0;
windowRect.right = (long)width;
windowRect.top = (long)0;
windowRect.bottom = (long)height;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //hInstance is NULL here, should it be something else?
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T("OpenGL");
wc.hIconSm = NULL;
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("Failed To Register The Window Class."), _T("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return false;
}
hInstance = wc.hInstance; //hInstance isn't NULL anymore
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle);
if(!(hWnd = CreateWindowEx(dwExStyle, _T("OpenGL"),
(wchar_t*)title,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
0, 0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
NULL,
NULL,
hInstance,
NULL))) {
DestroyGLWindow();
MessageBox(NULL, _T("Window Creation Error."), _T("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!(hDC = GetDC(hWnd))) {
DestroyGLWindow();
MessageBox(NULL, _T("Can't Create A GL Device Context."), _T("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return false;
}
PIXELFORMATDESCRIPTOR pfd2 = { sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if(!(pixelFormat = ChoosePixelFormat(hDC, &pfd2)) {
GLEngine is in a dll. It shouldn't matter but the information can't hurt.
Did you get address of function with GetProcAddress? Faulty drivers can cause crash on this too. ChoosePixelFormat may be implemented and exported driver-side, but it might be not exported, then system procedure should be used. exported one may or may not filling descriptor structure, depending on implementation, so you need to call DescribePixelFormat.
I've Created a custom .ico with VS2010 for a game I'm making with DirectX
When I set the .ico file as hIcon member of my wndClass, it will show in the taskbar, but not in the title bar.
I've read the other threads about this, I've searched google, msdn: no luck... I've tried just about anything I could come up with, it still wouldn't show.
The weird thing is: when I switch the hIcon to a default icon (like IDI_ERROR) it will show both in taskbar and in title bar, but not with my custom made .ico
Can anyone help me?
Here is my code:
HICON Icon = LoadIcon( NULL, MAKEINTRESOURCE(ID_ICON_MYTETRIS) );
WNDCLASS wndClass;
ZeroMemory(&wndClass,sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hIcon = Icon;
wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = _T("WindowClass0");
if (RegisterClass(&wndClass) == false) {
return -1;
}
RECT rc = {0,0,300,225};
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
HWND hWnd = CreateWindow(_T("WindowClass0")
,_T("2D_DirectX_Tetris")
,WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX
,CW_USEDEFAULT
,CW_USEDEFAULT
,rc.right - rc.left
,rc.bottom - rc.top
,NULL
,NULL
,hInstance
,NULL );
if( hWnd == false) {
return -1;
}
ShowWindow( hWnd, iCmdShow );
You have to specify an instance handle in your call to LoadIcon so it knows which module's resources to use.
The standard icons require a NULL instance, that's why they work for you.