I'm trying to create an OpenGL context with WinAPI, it works great, but I think I messed up something, because when I click on the upper bar (where close button, minimize button is), it calls the ResizeWindow function somehow...Image showing this
Here is my main function:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
GLWindow *window = new GLWindow();
Event *evt = new Event();
window->Create("OpenGL Window", 800, 600, 32);
while (window->IsRunning())
{
evt->Clear();
while (window->DispatchEvent(evt))
{
}
Render();
window->Present();
}
delete evt;
delete window;
}
Event is just a class with a map for containing event params. I removed every event handling in WndProc so it couldn't be a problem
Window creation code:
bool GLWindow::Create(char* title, int width, int height, int bits)
{
GLuint PixelFormat;
WNDCLASS wClass;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left = (long)0;
WindowRect.top = (long)0;
WindowRect.right = (long)width;
WindowRect.bottom = (long)height;
hInstance = GetModuleHandle(NULL);
wClass.cbClsExtra = 0;
wClass.cbWndExtra = 0;
wClass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
wClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wClass.hInstance = hInstance;
wClass.lpfnWndProc = &GLWindow::WndProc;
wClass.lpszClassName = "GL";
wClass.lpszMenuName = NULL;
wClass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
dwStyle = WS_OVERLAPPEDWINDOW;
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
if (!RegisterClass(&wClass))
{
MessageBox(NULL, "Error! Cannot register window class!", "ERROR", MB_OK);
return 0;
}
AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);
if (!(hWnd = CreateWindowEx(
dwExStyle,
"GL",
"Title",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
0,
0,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL)))
{
KillWindow();
MessageBox(NULL, "Window creation error.", "Error", MB_OK);
return false;
}
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1, //Version number
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA, //Formats
bits, //color depth
0, 0, 0, 0, 0, 0, //color bits ignored
0, //no alpha buffer
0, //shift bit ignored
0, //no accumulation buffer
0, 0, 0, 0, //accumulation bits ignored
16, //16bit Zbuffer (depth buffer)
0, //no stencilbuffer
0, //no auxiliary buffer
PFD_MAIN_PLANE, //main drawing layer
0, //reserved
0, 0, 0 //layer masks ignored
};
if (!(hDC = GetDC(hWnd)))
{
KillWindow();
MessageBox(NULL, "Can't create OpenGL Window", "Error", MB_OK);
return false;
}
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))
{
KillWindow();
MessageBox(NULL, "Can't find suitable PixelFormat", "Error", MB_OK);
return false;
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
{
KillWindow();
MessageBox(NULL, "Can't set pixelformat", "Error", MB_OK);
return false;
}
if (!(hRC = wglCreateContext(hDC)))
{
KillWindow();
MessageBox(NULL, "Can't create OpenGL context", "Error", MB_OK);
return false;
}
if (!wglMakeCurrent(hDC, hRC))
{
KillWindow();
MessageBox(NULL, "Can't activate OGL context", "Error", MB_OK);
return false;
}
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
ResizeWindow(800, 600);
if (!InitGL())
{
KillWindow();
MessageBox(NULL, "Failed initialization", "Error", MB_OK);
return false;
}
return true;
}
Dispatching events:
bool GLWindow::DispatchEvent(Event* evt)
{
MSG msg;
bool wasThereAnyEvent = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
if (wasThereAnyEvent)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return wasThereAnyEvent;
}
I removed event buffer filling, so it just processes every message.
WndProc:
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
break;
case WM_DESTROY:
case WM_QUIT:
case WM_CLOSE:
isRunning = false;
PostQuitMessage(0);
return 0;
case WM_ACTIVATE:
{
isActiveWindow = !HIWORD(wParam);
return 0;
}
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
case WM_SIZE:
ResizeWindow(LOWORD(lParam), HIWORD(lParam));
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
I think the problem is that you're not using any breaks inside you switch statement (of course they won't be needed in every case). When you receive a WM_SYSCOMMAND which not contains SC_SCREENSAVE or SC_MONITORPOWER the next case statement, in this case WM_SIZE, gets executed.
switch (msg)
{
case WM_CREATE:
break;
case WM_DESTROY:
case WM_QUIT:
case WM_CLOSE:
isRunning = false;
PostQuitMessage(0);
return 0;
break;
case WM_ACTIVATE:
{
isActiveWindow = !HIWORD(wParam);
return 0;
} break;
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
} break;
case WM_SIZE:
ResizeWindow(LOWORD(lParam), HIWORD(lParam));
return 0;
}
Related
I'd like to create a new POPUP style window in a new thread. Here is the code I have so far.
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <tchar.h>
#include <thread>
#include <string>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
using namespace std;
const wchar_t g_szClassName[] = L"Skeleton";
const wchar_t g_szChildClassName[] = L"Child";
wchar_t msgbuf[100];
char msgbuf_ansi[100];
WNDCLASSEX wc;
struct MyStruct
{
WNDCLASSEX wc;
HWND hWnd;
HINSTANCE hInst;
int nCmdShow;
};
MyStruct g_myStruct;
LRESULT CALLBACK WndProcChild(HWND, UINT, WPARAM, LPARAM);
void Example_DrawImage9(HDC hdc) {
Graphics graphics(hdc);
Image image(L"C:/Users/Darek/Fallout2_older/data/art/iface/armor_info.bmp");
graphics.DrawImage(&image, 0, 0);
}
int task1(MyStruct myStruct)
{
sprintf_s(msgbuf_ansi, ("thread\n"));
OutputDebugStringA(msgbuf_ansi);
HWND hwnd_child;
myStruct.wc.lpfnWndProc = WndProcChild;
myStruct.wc.lpszClassName = g_szChildClassName;
if (!RegisterClassEx(&myStruct.wc)) {
MessageBox(NULL, L"thread - Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd_child = CreateWindowEx(0, g_szChildClassName, L"Child", WS_POPUP | WS_BORDER, 200, 0, 190, 110, myStruct.hWnd, 0, myStruct.hInst, 0);
swprintf_s(msgbuf, _T("THREAD - CHILD - hwnd: %02X\n"), (int)hwnd_child);
OutputDebugString(msgbuf);
if (hwnd_child == NULL) {
MessageBox(NULL, L"thread - Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
SetWindowLong(hwnd_child, GWL_EXSTYLE, GetWindowLong(hwnd_child, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd_child, 0, 128, LWA_ALPHA);
ShowWindow(hwnd_child, myStruct.nCmdShow);
UpdateWindow(hwnd_child);
}
thread t1;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
//case WM_KEYDOWN:
case WM_CLOSE:
swprintf_s(msgbuf, _T("WM_CLOSE - PARENT \n"));
OutputDebugString(msgbuf);
if (MessageBox(hwnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}
return 0;
case WM_DESTROY:
swprintf_s(msgbuf, _T("WM_DESTROY - PARENT \n"));
OutputDebugString(msgbuf);
PostQuitMessage(0);
return 0;
case WM_CREATE: {
swprintf_s(msgbuf, _T("WM_CREATE - PARENT \n"));
OutputDebugString(msgbuf);
thread t1(task1, g_myStruct);
t1.join();
return 0;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int g_fMouseTracking = FALSE;
LRESULT CALLBACK WndProcChild(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
swprintf_s(msgbuf, _T("WM_PAINT - CHILD - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
hdc = BeginPaint(hwnd, &ps);
Example_DrawImage9(hdc);
EndPaint(hwnd, &ps);
return 0;
//case WM_KEYDOWN:
case WM_CREATE: {
swprintf_s(msgbuf, _T("WM_CREATE - CHILD \n"));
OutputDebugString(msgbuf);
return 0;
}
case WM_MOUSEMOVE:
swprintf_s(msgbuf, _T("WM_MOUSEMOVE - CHILD - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
if (!g_fMouseTracking)
{
// start tracking if we aren't already
TRACKMOUSEEVENT tme = {};
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = hwnd;
tme.dwHoverTime = HOVER_DEFAULT;
g_fMouseTracking = TrackMouseEvent(&tme);
}
return 0;
case WM_MOUSELEAVE:
swprintf_s(msgbuf, _T("WM_MOUSELEAVE - CHILD - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
g_fMouseTracking = FALSE; // tracking now canceled
return 0;
case WM_CLOSE:
swprintf_s(msgbuf, _T("WM_CLOSE - CHILD \n"));
OutputDebugString(msgbuf);
/*if (MessageBox(hwnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}*/
return 0;
case WM_DESTROY:
swprintf_s(msgbuf, _T("WM_DESTROY - CHILD \n"));
OutputDebugString(msgbuf);
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
//WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
ULONG_PTR token;
GdiplusStartupInput input = { 0 };
input.GdiplusVersion = 1;
GdiplusStartup(&token, &input, NULL);
//Step 1: Registering the Window Class
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(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);
g_myStruct.wc = wc;
g_myStruct.hInst = hInstance;
g_myStruct.nCmdShow = nCmdShow;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(0, g_szClassName, L"Skeleton", WS_BORDER, 0, 0, 190, 110, 0, 0, hInstance, 0);
g_myStruct.hWnd = hwnd;
if (hwnd == NULL) {
MessageBox(NULL, L"Parent Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
swprintf_s(msgbuf, _T("MAIN - PARENT - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd, 0, 128, LWA_ALPHA);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
The problems is that as I've debugged the child window is indeed created but automatically/magically destroyed when the WndProcChild returns.
How to correct the code to have it run as expected (the child window stays open until the main is't destroyed)?
The thread own the window it had created and its message queue and therefore must provide an event loop. It's destroyed because in Win API ownership is treated in RAII way - when owner ceases to exist, so do the acquired objects.
So basically I have this program that makes a transparent overlay for a game so I can make a kill counter. However, when I click on the game with the overlay on, nothing happens. I managed to make it so when you click on it then it sends a message to the game telling it to shoot, however, when I tried the same for moving my characters head it was just laggy and snappy. When I would move my head quickly, my cursor would also fly out of the game window. How can I fix this so when I play the game it would be like its not even there.
I have tried sending the message and setting the window active AND using setcapture. However, none of these worked. I have tried looking at other places but they didn't work either.
/* This is my while(true) loop: */
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg); // translates virtual-key messages into character messages
DispatchMessage(&msg); // dispatches a message to WindowProc
}
if (gameProcId == 0)
{
gameProcId = GetProcId(L"ac_client.exe");
}
if (gameWnd == NULL)
{
gameWnd = FindWindow(NULL, L"AssaultCube");
}
if ((gameProc == NULL) && (gameProcId != 0))
{
gameProc = OpenProcess(PROCESS_VM_READ, false, gameProcId); // opens an existing local process and returns a handle to it
}
if (gameProc != NULL)
{
if ((!init_ok) || ((loops % 20) == 0))
{
RECT client_rect;
#pragma warning (suppress: 6387)
GetClientRect(gameWnd, &client_rect); // gets a windows coordinates, upper-left corner is (0,0)
w_res.X = client_rect.right;
w_res.Y = client_rect.bottom;
RECT bounding_rect;
#pragma warning (suppress: 6387)
GetWindowRect(gameWnd, &bounding_rect); // gets dimensions of a window
if (!init_ok)
{
if ((w_pos.X != bounding_rect.left) || (w_pos.Y != bounding_rect.top))
{
MoveWindow(hWnd, bounding_rect.left, bounding_rect.top,
client_rect.right, client_rect.bottom, false);
w_pos.X = bounding_rect.left;
w_pos.Y = bounding_rect.top;
}
//SetCursorPos(w_pos.X * 4, w_pos.Y * 4);
//ClipCursor(&gameRect);
}
else
{
if ((bounding_rect.left == 0) && (bounding_rect.top == 0))
{
MoveWindow(hWnd, bounding_rect.left, bounding_rect.top, // changes both the position and dimension of a window
client_rect.right, client_rect.bottom, false);
}
MoveWindow(hWnd, bounding_rect.left, bounding_rect.top, client_rect.right,
client_rect.bottom, false);
}
init_ok = true;
}
}
if (loops % 10 == 0)
{
if (FindWindow(NULL, L"AssaultCube") == NULL)
{
SendMessage(hWnd, WM_CLOSE, NULL, NULL); // calls WindowProc() and sends the message to a window
}
}
loops++;
if (loops > 100) loops = 0;
Render();
}
}
/* This is my WindowProc() function: */
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}break;
case WM_LBUTTONDOWN:
{
PostMessage(gameWnd, message, wParam, lParam);
return 0;
}
case WM_MOUSEMOVE:
{
SendMessage(gameWnd, message, wParam, lParam);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
You didn't post enough code to attempt to solve this problem, we don't see your call to CreateWindowEx().
Here is a working solution for a win32 overlay:
#include <iostream>
#include <windows.h>
using namespace std;
//global forward declerations
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void cleanUpObjects(HPEN pen);
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
RECT overlayWindowRect;
RECT gameWindowRect;
HWND gameWindowHandle;
gameWindowHandle = FindWindowA(0, "AssaultCube");
GetWindowRect(gameWindowHandle, &gameWindowRect);
WNDCLASSEX w;
w.cbSize = sizeof(WNDCLASSEX);
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = NULL;
w.hCursor = NULL;
w.hbrBackground = (HBRUSH)0;
w.lpszMenuName = NULL;
w.lpszClassName = "ClassName";
w.hIconSm = NULL;
if (!RegisterClassEx(&w))
{
MessageBox(NULL, "Could not Register Class", "Window Title", NULL);
return -1;
}
HWND hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT, "ClassName", "Window",
WS_CAPTION,
gameWindowRect.left, //x
gameWindowRect.top, // y
gameWindowRect.right - gameWindowRect.left, // width
gameWindowRect.bottom - gameWindowRect.top, // height
NULL, NULL,
hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, "Call to create window failed", "Win32 Guided tour", NULL);
return -1;
}
else
{
GetWindowRect(hWnd, &overlayWindowRect);
}
// Remove Borders around window
SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~(WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_BORDER));
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) & ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
// Make the Background Transparent
SetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 255, LWA_COLORKEY); // Replaces color white with transparancey
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
HDC myHDC = GetDC(hWnd);
// Drawing Stuff
HPEN myPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
HPEN originalPen;
originalPen = (HPEN)SelectObject(myHDC, myPen);
//main loop waits for messages
MSG msg;
while (true)
{
//peekmessage allows for program to do multiple things at once. faster than getmessage()
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
// if msg is quit, quit
if (msg.message == WM_QUIT)
break;
}
else
{
Rectangle(myHDC, 200, 200, 300, 400);
ZeroMemory(&gameWindowRect, sizeof(gameWindowRect)); //clear out the struct
GetWindowRect(gameWindowHandle, &gameWindowRect); // retrieves the games xy and height width and stores in gamewindowrect
if (gameWindowRect.right != overlayWindowRect.right) // checks if the x coordinates are the same
{
ZeroMemory(&gameWindowRect, sizeof(gameWindowRect)); // clear out struct once again
GetWindowRect(gameWindowHandle, &gameWindowRect); // get the dimensions of the game window again
MoveWindow(hWnd, gameWindowRect.left, gameWindowRect.top, gameWindowRect.right - gameWindowRect.left, gameWindowRect.bottom - gameWindowRect.top, TRUE);
// moves window to specific spot
}
}
Sleep(5);
}
cleanUpObjects(myPen);
cleanUpObjects(originalPen);
return msg.wParam;
}
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
PAINTSTRUCT ps;
HDC hdc;
switch (uMsg)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DestroyWindow(hWnd);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return 0;
}
//cleans up objects
void cleanUpObjects(HPEN pen)
{
DeleteObject(pen);
}
I've recently gained interest in C++ and OpenGL programming, I've tried several types of code and they all run smoothly... then i was asked to test this code but for some reason i get errors all the time... and now i am lost on what i should do...
#define WIN32_LEAN_AND_MEAN //include only needed libraries
#include <windows.h> //include necessary windows definitions
#include <GL/glut.h> //include openGL functionality
#include "myMD2.h"
BOOL stillActive; //status checker
BOOL Keys[256]; //different keys that the user can click on
HDC global_Hdc; //Handle Device Context
int winWidth;
int winHeight;
myMD2 *myMD2;
LRESULT CALLBACK myWndProc(HWND hwnd, UINT uint, WPARAM wParam, LPARAM lParam);
void mySetPixel (HDC pixHDC);
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hThisTust, LPSTR lpArgs,int iCmd)
{
HWND myHwnd;
MSG myMsg;
WNDCLASSEX myWndClass;
static TCHAR myClass[] = TEXT("myclass");
myWndClass.cbClsExtra = 0;
myWndClass.cbSize = sizeof(WNDCLASSEX);
myWndClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
myWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
myWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
myWndClass.hIconSm = NULL;
myWndClass.hInstance = hThisTust;
myWndClass.lpfnWndProc = myWndProc;
myWndClass.lpszClassName = myClass;
myWndClass.lpszMenuName = NULL;
myWndClass.style =
CS_HREDRAW | CS_VREDRAW;
if(!RegisterClassEx(&myWndClass)){
MessageBox(NULL, TEXT("cannot register class"), TEXT("Error"), MB_OK | MB_ICONERROR);
return(0);
}
myHwnd = CreateWindowEx(WS_EX_APPWINDOW, myClass, NULL, WS_POPUP,0,0,1024,768,NULL, NULL, hThisTust, NULL);
if(!myHwnd){
MessageBox(NULL, TEXT("cannot create window"), TEXT("Error"), MB_OK | MB_ICONERROR);
return(0);
}
ShowWindow(myHwnd, iCmd);
UpdateWindow(myHwnd);
stillActive = TRUE;
while(stillActive){ //Entering game loop
if(PeekMessage(&myMsg, NULL, 0,0, PM_REMOVE) == WM_QUIT)
stillActive = FALSE;
else{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,1024,768);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,1024/768,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
myMD2 -> draw();
SwapBuffers(global_Hdc);
TranslateMessage(&myMsg);
DispatchMessage(&myMsg);
}
}
return myMsg.wParam;
}
LRESULT CALLBACK myWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
HDC myHdc;
HGLRC myHglrc; //Handle Graphics Library Resource Context
switch(msg){
case WM_CREATE:
myHdc = GetDC(hwnd);
global_Hdc = myHdc;
mySetPixel(myHdc);
myHglrc = wglCreateContext(myHdc);
wglMakeCurrent(myHdc, myHglrc);
myMD2 = new MYMD2();
myMD2->setup();
myMD2->angle += 180;
myMD2->obj3D.SetAnim(1);
return(0);
break;
case WM_KEYDOWN:
Keys[wParam] = TRUE;
if (Keys['Q']) //Keys[VK_ESCAPE]
stillActive = FALSE;
if (Keys[VK_SPACE]) //If the spacebar is pressed
myMD2->obj3D.SetAnim(6);
return(0);
break;
case WM_KEYUP:
if (Keys[VK_SPACE])
myMD2->obj3D.SetAnim(1);
Keys[wParam] = FALSE;
return(0);
break;
case WM_SIZE:
winWidth = LOWORD(lParam);
winHeight = HIWORD(lParam);
if (winHeight == 0)
winHeight = 1;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,1024,768);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,1024/768,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return(0);
break;
case WM_CLOSE:
if(myHdc){
ReleaseDC(hwnd, myHdc);
}
if(myHglrc){
wglMakeCurrent(NULL, NULL);
wglDeleteContext(myHglrc);
}
PostQuitMessage(0);
return(0);
break;
case WM_DESTROY:
if(myHdc){
ReleaseDC(hwnd, myHdc);
}
if(myHglrc){
wglMakeCurrent(NULL, NULL);
wglDeleteContext(myHglrc);
}
PostQuitMessage(0);
return(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
}
void mySetPixel(HDC myPixHdc){
int mySelected;
PIXELFORMATDESCRIPTOR pfd = {
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,
16,
0,
0,
PFD_MAIN_PLANE,
0,0,0,0
};
mySelected = ChoosePixelFormat(myPixHdc, &pfd);
SetPixelFormat(myPixHdc, mySelected, &pfd);
}
myMD2.h
#ifndef MY_MD2_H
#define MY_MD2_H
typedef void* md2_t;
md2_t md2_open(const char *filename);
void md2_close(md2_t h);
void md2_desc(md2_t h);
void md2_frame_sample(md2_t _h);
void md2_draw(md2_t h);
#endif
The headerfile myMD2.h does not define a class or struct called myMD2. From the rest of your code I would guess that you have downloaded the wrong header file.
I do not see where the error is. The window display only the first character you type, and the other is not. Although the cursor moves when typing. And when minimize and maximize the window, the text becomes visible.
#include <windows.h>
#define IDI_MYICON 201
#define IDR_MYMENU 201
#define ID_FIO_FirstName 4002
#define ID_FIO_SecondName 4003
#define ID_FIO_Name 4001
#define ID_INFO_DeveloperStatus 9002
#define ID_INFO_LearningForm 9003
#define ID_INFO_Group 9004
#define BUFSIZE 6665535
#define SHIFTED 0x8000
const char g_szClassName[] = "MFW";
LONG APIENTRY WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
TEXTMETRIC tm;
static DWORD dwCharX;
static DWORD dwCharY;
static DWORD dwClientX;
static DWORD dwClientY;
static DWORD dwLineLen;
static int nCaretPosX = 0;
static int nCaretPosY = 0;
static int nCharWidth = 0;
static int cch = 0;
static int nCurChar = 0;
static PTCHAR pchInputBuf;
int i, j;
int cCR = 0;
int nCRIndex = 0;
int nVirtKey;
TCHAR szBuf[128];
TCHAR ch;
PAINTSTRUCT ps;
RECT rc;
SIZE sz;
COLORREF crPrevText;
COLORREF crPrevBk;
switch(Message)
{
case WM_CREATE:
{
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
ReleaseDC(hwnd, hdc);
dwCharX = tm.tmAveCharWidth;
dwCharY = tm.tmHeight;
pchInputBuf=(LPTSTR)GlobalAlloc(GPTR,BUFSIZE*sizeof(TCHAR));
HMENU hMenu, hSubMenu;
HICON hIcon, hIconSm;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FIO_FirstName, "FirstName");
AppendMenu(hSubMenu, MF_STRING, ID_FIO_SecondName, "SecondName");
AppendMenu(hSubMenu, MF_STRING, ID_FIO_Name, "Name");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&FIO");
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_INFO_DeveloperStatus, "DeveloperStatus");
AppendMenu(hSubMenu, MF_STRING, ID_INFO_LearningForm, "LearningForm");
AppendMenu(hSubMenu, MF_STRING, ID_INFO_Group, "Group");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&INFO");
SetMenu(hwnd, hMenu);
hIcon =(HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if(hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
else
MessageBox(hwnd, "Could not load large icon!","Error", MB_OK | MB_ICONERROR);
hIconSm =(HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
if(hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
else
MessageBox(hwnd, "Could not load small icon!","Error", MB_OK | MB_ICONERROR);
break;
}
break;
case WM_PAINT:
if (cch==0)break;
hdc=BeginPaint(hwnd,&ps);
HideCaret(hwnd);
SetRect(&rc, 0, 0, dwLineLen, dwClientY);
DrawText(hdc, pchInputBuf,-1,&rc,DT_NOCLIP);
ShowCaret(hwnd);
EndPaint(hwnd, &ps);
break;
case WM_SIZE:
dwClientX=LOWORD(lParam);
dwClientY = HIWORD(lParam);
dwLineLen=dwClientX-dwCharX;
break;
case WM_SETFOCUS:
CreateCaret(hwnd, (HBITMAP) 0,3, dwCharY);
SetCaretPos(nCaretPosX,nCaretPosY*dwCharY);
ShowCaret(hwnd);
break;
case WM_KILLFOCUS:
HideCaret(hwnd);
DestroyCaret();
break;
case WM_CHAR:
if (cch > BUFSIZE-5)
{
pchInputBuf[cch] = 0x00;
SendMessage(hwnd,WM_PAINT, 0, 0);
}
switch (wParam)
{
case 0x08:
case 0x0A:
case 0x1B:
MessageBeep(0xFFFFFFFF);
return 0;
case 0x09:
for (i = 0; i < 4; i++)
SendMessage(hwnd, WM_CHAR, 0x20, 0);
return 0;
case 0x0D:
pchInputBuf[cch++] = 0x0D;
nCaretPosX = 0;
nCaretPosY += 1;
break;
default:
ch =(TCHAR)wParam;
HideCaret(hwnd);
hdc = GetDC(hwnd);
GetCharWidth32(hdc,wParam,wParam,&nCharWidth);
DrawText(hdc, pchInputBuf,-1,&rc, DT_NOCLIP);
ReleaseDC(hwnd, hdc);
pchInputBuf[cch++] = ch;
nCaretPosX += nCharWidth;
if ((DWORD) nCaretPosX > dwLineLen)
{
nCaretPosX = 0;
pchInputBuf[cch++] = 0x0D;
++nCaretPosY;
}
nCurChar = cch;
ShowCaret(hwnd);
break;
}
SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_LEFT:
if (nCaretPosX > 0)
{
HideCaret(hwnd);
ch = pchInputBuf[--nCurChar];
hdc = GetDC(hwnd);
GetCharWidth32(hdc, ch, ch, &nCharWidth);
ReleaseDC(hwnd, hdc);
nCaretPosX = max(nCaretPosX - nCharWidth, 0);
ShowCaret(hwnd);
} break;
case VK_RIGHT:
if (nCurChar > cch) {
HideCaret(hwnd);
ch = pchInputBuf[nCurChar];
if (ch == 0x0D) {
nCaretPosX = 0;
nCaretPosY++;
}
else {
hdc = GetDC(hwnd);
nVirtKey = GetKeyState(VK_SHIFT);
if (nVirtKey & SHIFTED) {
crPrevText = SetTextColor(hdc,RGB(255, 255, 255));
crPrevBk = SetBkColor(hdc,RGB(0,0,0));
TextOut(hdc, nCaretPosX,nCaretPosY * dwCharY,&ch,1);
SetTextColor(hdc, crPrevText);
SetBkColor(hdc, crPrevBk);
}
GetCharWidth32(hdc, ch, ch, &nCharWidth);
ReleaseDC(hwnd, hdc);
nCaretPosX = nCaretPosX + nCharWidth;
}
nCurChar++;
ShowCaret(hwnd);
break;
}
break;
case VK_HOME:
nCaretPosX = nCaretPosY = 0;
nCurChar = 0;
break;
case VK_END:
for (i=0; i < cch; i++)
{
if (pchInputBuf[i] == 0x0D) {
cCR++;
nCRIndex = i + 1;
}
}
nCaretPosY = cCR;
for (i = nCRIndex, j = 0; i < cch; i++, j++)
szBuf[j] = pchInputBuf[i];
szBuf[j] = TEXT('\0');
hdc = GetDC(hwnd);
GetTextExtentPoint32(hdc,szBuf,lstrlen(szBuf),&sz);
nCaretPosX = sz.cx;
ReleaseDC(hwnd, hdc);
nCurChar = cch;
break;
default:
break;
}
SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FIO_FirstName:
MessageBox(hwnd, "F-3", "FirstName", 0);
break;
case ID_FIO_SecondName:
MessageBox(hwnd, "B-2", "SecondName", 0);
break;
case ID_FIO_Name:
MessageBox(hwnd, "A-1", "Name", 0);
break;
case ID_INFO_DeveloperStatus:
MessageBox(hwnd, "S", "DeveloperStatus", 0);
break;
case ID_INFO_LearningForm:
MessageBox(hwnd, "FORM", "LearningForm", 0);
break;
case ID_INFO_Group:
MessageBox(hwnd, "GR", "Group", 0);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
GlobalFree((HGLOBAL) pchInputBuf);
UnregisterHotKey(hwnd, 0xAAAA);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_MYICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
wc.lpszClassName = g_szClassName;
wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_MYICON),IMAGE_ICON,16,16, 0);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
g_szClassName,
"QWERTY",
WS_OVERLAPPEDWINDOW,
200, 100, 800, 600,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
You use WM_PAINT incorrectly. You shouldn't send it manually. You need to call InvalidateRect(hwnd, NULL, true); instead of SendMessage(hwnd,WM_PAINT, 0, 0); and it will post a WM_PAINT message to your WndProc correctly.
When you minimize/maximize the window, Windows call internally something like InvalidateRect(hwnd, NULL, true);
Addition by manuell:
Also always call BeginPaint/EndPaint in WM_PAINT handler (you shouldn't break before calling BeginPaint/EndPaint).
I'm trying to create a second window if a dialog box from my first window returns a certain way. Unfortunately, if I call CreateWindowEx() from within the callback process of the first window, it doesn't recognise the second window's HWND. I also tried defining the first window in WinMain and making it visible within the callback, but it failed to recognise the HWND once again. Am I trying to do this wrong, or am I just missing something?
Edit:
#include "stdafx.h"
#include "md5.h"
#include "Coursework.h"
#include "accounts.h"
const char g_szClassName[] = "myMainWindow";
const char g_szLoggedInClass[] = "loggedInWindow";
#define IDC_CREATE_ACCOUNT 101
#define IDC_LOG_IN 110
MYSQL *conn;
static std::string strUserName;
BOOL CALLBACK CreateDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
CreateAccount(hwnd);
}
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
default:
return FALSE;
}
}
BOOL CALLBACK LogInDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
case IDOK:
{
if(bLogIn(hwnd, strUserName))
{
EndDialog(hwnd, IDOK);
}
}
break;
}
break;
default:
return FALSE;
}
}
LRESULT CALLBACK LoggedInProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_CREATE:
{
if (*mysql_error(conn)) //Checks if the connection succeeded, and
{ //exits the program if false.
MessageBox(hwnd, "No connection to the server could be established.\r\nPlease contact your administrator.", "Error", MB_ICONERROR);
exit(-1);
}
HWND hCreateButton = CreateWindowEx(NULL, "Button", "Create account", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 500, 250, 120, 24, hwnd, (HMENU)IDC_CREATE_ACCOUNT, GetModuleHandle(NULL), NULL);
HWND hLogInButton = CreateWindowEx(NULL, "Button", "Log in", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 500, 210, 120, 24, hwnd, (HMENU)IDC_LOG_IN, GetModuleHandle(NULL), NULL);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CREATE_ACCOUNT:
{
int ret = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, CreateDlgProc);
if (ret == -1)
{
MessageBox(hwnd, "Dialog failed to appear", "Error", MB_OK | MB_ICONINFORMATION);
}
}
break;
case IDC_LOG_IN:
{
int ret = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG2), hwnd, LogInDlgProc);
if(ret == -1)
{
MessageBox(hwnd, "Dialog failed to appear", "Error", MB_OK | MB_ICONINFORMATION);
}
else if(ret == IDOK)
{
ShowWindow(hwnd, SW_HIDE);
}
}
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
WNDCLASSEX wc2;
HWND hwnd;
HWND hLoggedIn;
MSG Msg;
conn = mysql_init(NULL); //Initialises mySQL connection
mysql_real_connect(conn, "localhost", "root", "SecurityRules", "coursework", 0, NULL, 0);
//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);
//Registering the second Window Class
wc2.cbSize = sizeof(WNDCLASSEX);
wc2.style = 0;
wc2.lpfnWndProc = LoggedInProc;
wc2.cbClsExtra = 0;
wc2.cbWndExtra = 0;
wc2.hInstance = hInstance;
wc2.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc2.hCursor = LoadCursor(NULL, IDC_ARROW);
wc2.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc2.lpszMenuName = NULL;
wc2.lpszClassName = g_szLoggedInClass;
wc2.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!\r\nContact your administrator.", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
if(!RegisterClassEx(&wc2))
{
MessageBox(NULL, "Window Registration failed!\r\nContact your administrator.", "Error!", MB_ICONEXCLAMATION|MB_OK);
return 0;
}
//Creating the main Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "Coursework", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1080, 640, NULL, NULL, hInstance, NULL);
hLoggedIn = CreateWindowEx(WS_EX_CLIENTEDGE, g_szLoggedInClass, "Coursework", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1080, 640, NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!\r\nContact your adminstrator.", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
mysql_close(conn);
return Msg.wParam;
}
}
Edit 2:
Intellisense (I'm in Visual Studio) states that 'identifier hLoggedIn is undefined', as well as nCmdShow.