I want to make a popup window appear when I hit a button that is located on the main window of my program. I have looked everywhere for popup window examples, and most answers just showed me how to make a window, buttt I already have a main window in my application.
Basically the difficulty I am having is knowing where to put the new window class and code for my popup window(since I want the pop window to have different properties than my main one). Should it also be in the WinMain function or should it be in one of the cases in the CALLBACK WndProcedure section?
some of the code I have for my window is:
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
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 = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
I just am not sure where to put it... Should it be placed in the code that is activated when the button is pressed, or should it stay in the WinMain function, together with the information of the other window?
I hope you can understand my predicament, I am somewhat new to programming.
Register window at main() together with main window. And in case statement of WndProc call CreateWindowEx().
But I don't know how make animation of popup. I can imagine that code should put somewhere in the WM_CREATE, but this I don't know.
if you mean just another window for example window for settings you should use DialogBoxes.
P.S. If you are russian, then I strongly recommend the book "Win32 API. Effective Application Development" by Yuri Shchupak on russian
The new window should be created in the case statement in your wndProc that handles the button click.
Related
I have a problem with setting the titlebar icon for my application.
I have been trying to figure this out, Googling what is wrong, for 2 days already, without any success.
MainWindow.cpp:
#include "../../res/Icons.h"
void MainWindow::Create(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"MainWindow";
WNDCLASSEX wc = {};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hIcon = LoadIcon(NULL,IDI_MYICON);
wc.hIconSm = LoadIcon(NULL,IDI_MYICON);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(255,255,255));
RegisterClassEx(&wc);
HWND hwnd = CreateWindowEx(0, CLASS_NAME, wstring(Language::wText[1].begin(),Language::wText[1].end()).c_str(), WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Icons.h
#define IDI_MYICON 1000
Icons.rc
IDI_MYICON ICON "App.ico"
It compiles fine, and the icon is shown in the Taskbar, as well as in the executable file, but not in the titlebar. The icon is a standard ico with dimensions of 32x32. I have even tried using LoadImage(), but same result.
You are passing NULL to LoadIcon, you should pass the HINSTANCE of your application to load from your own resources.
The resource header file needs to be used in conjunction with the .rc file (i.e. #include "icon. h" in icon. rc), otherwise the specific icon file (path is specified in the .rc file) will not be found. In addition, if "icon.h" does not end with an empty line, you will get an unexpected end of file found error.
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've been trying to make a keyboard shortcut in my Win32 application. It is an F5 refresh shortcut.
I've been following this example: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646337%28v=vs.85%29.aspx#wm_command.
I've included this in a "menu.rc" file:
IDR_MYACC ACCELERATORS
BEGIN
VK_F5, ID_EDIT_REFRESH, VIRTKEY
END
And this in the "main.cpp" file:
HWND hwnd;
HANDLE hinstAcc;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("CPUTemp");
MSG msg;
WNDCLASSEX wc;
BOOL bRet;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON),
IMAGE_ICON, 16, 16, 0);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // use default colour as window background
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, szAppName, "CPU Temperature", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 150, NULL, NULL, hInstance, NULL);
ShowWindow(GetConsoleWindow(), 0);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
HACCEL haccel = LoadAccelerators(hinstAcc, MAKEINTRESOURCE(IDR_MYACC));
if (haccel == NULL) {
MessageBox(NULL, "Accelerator Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// get and dispatch messages until a WM_QUIT message is received
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1) {
MessageBox(NULL, "Message Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
} else {
// Check for accelerator keystrokes
if (!TranslateAccelerator(
hwnd, // handle to receiving window
haccel, // handle to active accelerator table
&msg)) // message data
{
TranslateMessage(&msg); // translate virtual-key messages into character messages
DispatchMessage(&msg); // send message to window procedure
}
}
}
return msg.wParam; // the program return-value is 0 - value that PostQuitMessage() gave
}
The problem occurs when compiling - I get an error saying "invalid conversion from 'HANDLE aka void' to 'HINSTANCE' for this line:
HACCEL haccel = LoadAccelerators(hinstAcc, MAKEINTRESOURCE(IDR_MYACC));
But if I try replacing "hinstAcc" with "hInstance", it compiles and runs, but the accelerator ends up being NULL.
How do I fix this?
re the compilation problem:
use hInstance, or better, use GetModuleHandle(0) and ditch the silly, verbose and non-standard WinMain (use standard main instead)
more generally, just consult the documentation about Windows API function arguments
e.g. google LoadAccelerators, click on the link to MSDN docs.
re
“ if I try replacing "hinstAcc" with "hInstance", it compiles and runs, but the accelerator ends up being NULL.”
I can't see any reason in the provided code.
Maybe you've forgot to link in the resources.
I have a main window which has a child window which in turn have a child window and a button. When i restore the window from taskbar the button and third child window refuse to display. I tried using RedrawWindow() on the child first, and then the grand child and the button but didnt work. So far it looks like there is no connection between the child window and its child cos the parent is responsible for repainting its child, but the child has no duty. How do i repaint child window's controls / child window (child of a child), during parent (main window) repaint. That is after restore of parent using Win32 API.
I created a control class as the entry point of the app and to oversee all other classes(Screen class- for GUI, Database class...), the Screen class have all the child creation codes in it. This how:
//MainControl Class
#include <tchar.h>
#include "Screen.h"
#include <stdlib.h>
#include "FreeImage.h"
#pragma comment(lib, "user32")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"FreeImage.lib")
const char g_szClassName[] = "myWindowClass";
Screen display;
HWND welcomScreenHndl, menuScreenHndl, butt;
// Function prototypes
LRESULT CALLBACK WndProc(HWND hwnd, UINT messages, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow){
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// Registering the Window Class.
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 = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)){
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Creating the Window.
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName,
"Prison Management System",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
100, 30, 750, 700, NULL, NULL, hInstance, NULL);
if(hwnd == NULL){
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Creating Other Windows with Scree class object.
welcomScreenHndl = display.welcomeScreen(hwnd, hInstance);//Child to Main Window
menuScreenHndl = display.menuScreen(welcomScreenHndl, hInstance);//grand child
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// The message loop.
while(GetMessage(&Msg, NULL, 0, 0) > 0){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Here is the Screen class: // Screen Class
#include <tchar.h>
#include <windows.h>
class Screen{
char winClassName[20];
public:
HWND welcomeScreen(HWND parent, HINSTANCE hInstance);
HWND menuScreen(HWND parent, HINSTANCE hInstance);
};
HWND Screen::welcomeScreen(HWND parent, HINSTANCE hInstance){
GetClassName(parent, winClassName, 20);
HWND hwndpan = CreateWindowEx( WS_EX_CLIENTEDGE,
winClassName,
"",
WS_CHILD | WS_VISIBLE | CS_HREDRAW | CS_VREDRAW,
0, 20, 745, 695,
parent, NULL, hInstance/*GetModuleHandle(NULL)*/, NULL);
return hwndpan;
}
HWND Screen::menuScreen(HWND parent, HINSTANCE hInstance){
HWND hwndpan = CreateWindowEx( WS_EX_CLIENTEDGE,
winClassName,
"",
WS_CHILD | WS_VISIBLE | CS_HREDRAW | CS_VREDRAW,
0, 100, 745, 695,
parent, NULL, hInstance/*GetModuleHandle(NULL)*/, NULL);
return hwndpan;
}
I was wondering how can I create a window using Win32 API with a specific client area size.
When trying to create a window using the following piece of code, the entire window is 640x480, with the window's chrome taking some of the client area:
HWND hWnd;
WNDCLASSEX WndClsEx;
ZeroMemory(&WndClsEx, sizeof(WNDCLASSEX));
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = DefWindowProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = TEXT("Title");
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&WndClsEx);
hWnd = CreateWindowEx( NULL,
TEXT("Title"),
TEXT("Title"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640,
480,
NULL,
NULL,
hInstance,
NULL);
Assuming simple math won't quite solve the problem, how do I take the chrome size into account?
Note: I'm using SDL after creating the window, but I'm guessing it's bound to the window size and makes no difference to its size.
You can use the AdjustWindowRect or AdjustWindowRectEx function to calculate the window size given a desired client area size.