Programming Windows Compiler Link Error - unresolved external - windows

I am new to Windows Programming.
I created a win32 console project (without preCompiled header) with VS2005. And the code as below.
// HelloWin.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include "stdafx.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int _tmain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWin");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This Program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, // window class name
TEXT("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
case WM_CREATE:
PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello Windows XP"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
And now there is two Link Errors as this, Could anybody help me to fix this errors.
Does it caused by there is no hellowin.wav file in my local harddisk? If it does. What directory can I place a simular WAV file to?
Thanks.
1>Linking... 1>HelloWin.obj :
error LNK2019: unresolved external
symbol imp__PlaySoundW#12 referenced in function "long __stdcall
WndProc(struct HWND *,unsigned int,unsigned int,long)"
(?WndProc##YGJPAUHWND__##IIJ#Z)
1>D:\learning\windows\ProgrammingWindows(5thEdition)\HelloWin\Debug\HelloWin.exe
:
fatal error LNK1120: 1 unresolved externals 1>Build log was saved at
"file://d:\learning\windows\ProgrammingWindows(5thEdition)\HelloWin\HelloWin\Debug\BuildLog> .htm"
1>HelloWin - 2 error(s), 1 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

You have several problems here. Firstly you say that your application is a console app. If it is, then you are using the wrong main. Your subsystem is probably WINDOWS in which case your main should be this instead:
int CALLBACK _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR szCmdLine, int iCmdShow)
You also say you're not using precompiled headers but you have an include for stdafx.h. Your problems can be fixed by changing your main and also changing your includes to look like this:
#include <windows.h>
#include <tchar.h>
#pragma comment(lib, "Winmm.lib")
This allows the linker to look for the library file we tell it to. I also got rid of your precompiled header and replaced it with tchar.h since that is your only other dependency so far.
The fact hellowin.wav is not present at compilation time is irrelevant. The program only looks for it at runtime.

Related

Is there a way to get the handle of the entry field in a date time picker (DTP)?

The DATETIMEPICKERINFOstructure obtained by sending the DTM_GETDATETIMEPICKERINFOmessage has a field hwndEdit which might be what I'm looking for. However, I'm getting always NULL for it so I'm wondering what's its actual meaning. If not, is there a way to get the handle of the entry field?
hwndEdit only seems to be valid when the control has the DTS_APPCANPARSE style and you click the date text with the mouse (I tested this with OutputDebugString and a timer). The edit control is created and destroyed dynamically. The hwndUD handle is only valid if DTS_UPDOWN is set and the hwndDropDown is only valid while the dropdown is visible.
It is not called out in the documentation but DTM_GETDATETIMEPICKERINFO is marked Vista+ and this often means the feature is only implemented in ComCtl32 v6 so you also have to make sure you have a manifest that requests this version.
To change the color you can try DTM_SETMCCOLOR but only MCSC_BACKGROUND is documented to work when Visual Styles are active.
I'm afraid there is no way to get what you wanted. I just created a simple Win32 application just to test the possibility. If I use the DTM_GETDATETIMEPICKERINFO, hwndDropDown, hwndEdit and hwndUD give me NULL. If I try to enum child window, well before I do so I check it with Spy++, no luck, there is no child window associated with it.
Finally, I tried GetFocus() and WindowFromPoint(), both give me the HWND of the DateTimePicker itself only.
Here is my testing code:
#pragma comment(lib, "comctl32.lib")
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>
enum MYID {
MYID_FIRST = WM_APP,
MYID_DTP
};
LPCTSTR const g_MyWndClass = _T("DTPTest");
LPCTSTR const g_MyWndTitle = _T("DTPTest");
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void OnWindowCreate(HWND);
void OnTimer(HWND);
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int nCmdShow)
{
INITCOMMONCONTROLSEX icex{};
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_DATE_CLASSES;
InitCommonControlsEx(&icex);
WNDCLASSEX wcex{};
wcex.cbSize = sizeof(wcex);
wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = g_MyWndClass;
wcex.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wcex);
HWND hwnd = CreateWindowEx(0,
g_MyWndClass, g_MyWndTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 600, 400,
nullptr, nullptr, nullptr, nullptr);
if (!hwnd) { return 99; }
SetTimer(hwnd, 0, 100, nullptr);
ShowWindow(hwnd, nCmdShow);
MSG msg{};
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l)
{
switch (msg) {
case WM_CREATE:
OnWindowCreate(hwnd);
break;
case WM_TIMER:
OnTimer(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, w, l);
}
return 0;
}
void OnWindowCreate(HWND hwnd)
{
HWND hwndDTP = CreateWindowEx(0, DATETIMEPICK_CLASS, nullptr,
WS_CHILD | WS_VISIBLE | DTS_SHOWNONE,
20, 50, 220, 20,
hwnd, reinterpret_cast<HMENU>(MYID_DTP), nullptr, nullptr);
DATETIMEPICKERINFO info{};
info.cbSize = sizeof(DATETIMEPICKERINFO);
SendMessage(hwndDTP, DTM_GETDATETIMEPICKERINFO, 0,
reinterpret_cast<LPARAM>(&info));
if (!info.hwndDropDown && !info.hwndEdit && !info.hwndUD)
{
MessageBox(hwnd, _T("No luck with DTM_GETDATETIMEPICKERINFO"),
nullptr, MB_ICONERROR);
}
}
void OnTimer(HWND hwnd)
{
POINT pt{};
GetCursorPos(&pt);
HWND hwndPoint = WindowFromPoint(pt);
HWND hwndFocus = GetFocus();
TCHAR buf[99]{};
wsprintf(buf, _T("Pointing at %p, focusing %p"),
hwndPoint, hwndFocus);
SetWindowText(hwnd, buf);
}

Under what conditions will SendMessageTimeout(...,SMTO_NORMAL,...) ignore the timeout parameter when sending to another process?

Reading the documentation for SendMessageTimeout I thought the only time SendMessageTimeout would ignore the timeout parameter was when either:
The target window belongs to the same thread
Or "If the window receiving the message belongs to the same queue as the current thread[...]"
But I've encountered a case where either I'm misunderstanding what MSDN means by "same queue" or something else is going on.
When MSDN writes same queue, I'm thinking they're referring to the issues related to using AttachThreadInput, which I know from reading The Old New Thing is potentially dangerous.
I've tried my best at producing a minimal example, that hopefully still reflects the actual case I've encountered. I'm not looking for specific workarounds as I already have lots of options for avoiding this exact issue.
In short process A periodically broadcasts a message to all windows. Process B monitors process A and at some point decides to politely ask it to close. Process B uses SendMessageTimeout to allow for the case where process A has unsaved changes and puts up a dialog in its WM_CLOSE handler.
I've tested this on Win8.1 and Win10. Compiled using MSVC2015 Update 2 and 3, but I don't think anything is MSVC/MSVC version/C(++) specific.
Compile and run: cl /nologo /W4 /EHsc a.cpp user32.lib && cl /nologo /W4 /EHsc b.cpp user32.lib && a.exe && b.exe
This should bring up a "Waiting" dialog in process A. I was expecting process B to display an error dialog saying SendMessageTimeout failed, but it doesn't. It hangs until the dialog is closed in process A.
// a.cpp
#include <windows.h>
#define CLASS_NAME TEXT("A_WINDOW_CLASS")
LRESULT CALLBACK WndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
static UINT uCommonMsg = RegisterWindowMessage(TEXT("CommonMsg"));
const int nTimerId = 100;
DWORD_PTR dwResult;
switch (uiMsg) {
case WM_CREATE:
return SetTimer(hwnd, nTimerId, 1000, nullptr);
case WM_DESTROY:
KillTimer(hwnd, nTimerId);
PostQuitMessage(0);
break;
case WM_TIMER:
SendMessageTimeout(HWND_BROADCAST, uCommonMsg, 0, 0, SMTO_NORMAL, 1000, &dwResult);
return 0;
case WM_CLOSE:
MessageBox(hwnd, TEXT("Waiting..."), CLASS_NAME, MB_OK);
break;
}
return DefWindowProc(hwnd, uiMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int)
{
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = CLASS_NAME;
if (!RegisterClass(&wc)) return GetLastError();
HWND hwnd = CreateWindow(CLASS_NAME, CLASS_NAME, WS_VISIBLE|WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hinst, 0);
if (!hwnd) return GetLastError();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// b.cpp
#include <windows.h>
HWND hwndAWindow;
int nReceived;
LRESULT CALLBACK WndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
static UINT uCommonMsg = RegisterWindowMessage(TEXT("CommonMsg"));
if (uiMsg == uCommonMsg) {
++nReceived;
return 0;
}
DWORD_PTR dwResult;
switch (uiMsg) {
case WM_CREATE: return uCommonMsg != 0;
case WM_DESTROY: PostQuitMessage(0); break;
case WM_USER:
// Ask window A to close
if (!SendMessageTimeout(hwndAWindow, WM_CLOSE, 0, 0, SMTO_NORMAL, 5000, &dwResult)) {
MessageBox(hwnd, TEXT("SendMessageTimeout failed"), TEXT("Error"), MB_ICONERROR|MB_OK);
}
SendMessage(hwnd, WM_CLOSE, 0, 0); // We're done
return 0;
}
return DefWindowProc(hwnd, uiMsg, wParam, lParam);
}
#define CLASS_NAME TEXT("B_WINDOW_CLASS")
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int) {
hwndAWindow = FindWindow(TEXT("A_WINDOW_CLASS"), nullptr);
if (!hwndAWindow) return -1;
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = CLASS_NAME;
if (!RegisterClass(&wc)) return GetLastError();
HWND hwnd = CreateWindow(CLASS_NAME, CLASS_NAME, WS_VISIBLE|WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hinst, 0);
if (!hwnd) return GetLastError();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
// Once we're sure A is up and running ask window B to do its thing
if (nReceived) {
PostMessage(hwnd, WM_USER, 0, 0);
}
}
return 0;
}
You probably want
if (!SendMessageTimeout(hwndAWindow, WM_CLOSE, 0, 0, SMTO_NORMAL | SMTO_ABORTIFHUNG, 5000, &dwResult))
in b.cpp.
Also, WM_CLOSE can't be sent - it can only be posted. Sending WM_CLOSE cross-thread often ends up with an RPC_E_CANTCALLOUT_ININPUTSYNCCALL error.

WinApi DrawText and TextOut cannot display unicode character U+5167

Hello Windows Programmers!
I am new to windows programming using winapi. I was reading this very nice book and I encountered a problem(displayed as a black box) when I display unicode character U+5167 (內) in the client area using DrawText and TextOut. Mysteriously, this particular unicode character is properly displayed in windows caption area. This unicode character is also displaying correctly when I display it using the MessageBox. Finally, I tried displaying other unicode characters that are relatively near to this unicode like U+5166, U+5168, U+5157 and U+5177;
Here's a link for this unicode character as defined by the standards.
http://unicode-table.com/en/#5167
Note : I am compiling this code using Unicode using Visual Studio 2010
Below is my code.
#include<windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWin");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if(!RegisterClass (&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName,
TEXT("內Sample text 內篇 日本国 渡瀬 內篇全兦兗具 кошка"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
LPTSTR c = TEXT("內Sample text 內篇 日本国 渡瀬 內篇全兦兗具 кошка");
switch(message)
{
case WM_CREATE:
PlaySound(TEXT("shutda.wav"), NULL, SND_FILENAME | SND_ASYNC);
MessageBox(hwnd, c, c, 0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawTextEx(hdc, c, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER, NULL);
TextOut(hdc, 100, 100, TEXT("內篇 日本国 кошка unicode"), 19);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
For non windows programmers, you can compile and run this code by copy and pasting this directly to a .cpp file. If you are using VS2010, you just need to create new "Win32 Application" project and select "Empty Project". After that, you need to add a cpp file for example "test.cpp" in the source folder of your project. Then copy and past the code
to the "test.cpp" then build and run it. You should now see my problem. :)
When a valid character is displayed as a rectangular box, that indicates that the font does not contain a glyph for the characters. In order to solve the problem you need to use a font which does have a glyph for this character.

SysAnimate32 on Windows 7 and 8

This code no longer works on Windows 7 or 8.
Aren't SysAnimate32 controls supported on them ?
Is there a way to make it work as it used to work on Windows XP ?
(I am required to write more details but I have no more details to talk about :)
thanks
#include <windows.h>
#include <CommCtrl.h>
HINSTANCE hInstance;
#define IDC_MYANIMATE 9
HWND CreateAnimationControl (HWND hParent)
{
HWND hAnimation = Animate_Create( hParent, IDC_MYANIMATE, ACS_AUTOPLAY | WS_BORDER | WS_CHILD, hInstance);
Animate_Open (hAnimation, "test.avi");
ShowWindow (hAnimation, SW_SHOW);
return hAnimation;
}
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hAnimation = NULL;
switch (uiMsg)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_CREATE:
hAnimation = CreateAnimationControl (hWnd);
break;
case WM_SHOWWINDOW:
if (wParam)
{
MoveWindow (hAnimation, 0, 0, 300, 300, TRUE);
Animate_Play (hAnimation, 0, -1, -1);
}
break;
}
return DefWindowProc (hWnd, uiMsg, wParam, lParam);
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpsCmdLine, int iCmdShow)
{
WNDCLASSEX WindowClass;
HWND hWnd;
MSG uMsg;
hInstance = GetModuleHandle (NULL);
WindowClass.cbClsExtra = 0;
WindowClass.cbSize = sizeof (WNDCLASSEX);
WindowClass.cbWndExtra = 0;
WindowClass.hbrBackground = CreateSolidBrush (RGB (0, 0, 0));
WindowClass.hCursor = LoadCursor (NULL, IDC_ARROW);
WindowClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
WindowClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
WindowClass.hInstance = hInstance;
WindowClass.lpfnWndProc = WindowProcedure;
WindowClass.lpszClassName = "1";
WindowClass.lpszMenuName = NULL;
WindowClass.style = 0;
if (!RegisterClassEx (&WindowClass))
{
MessageBox (NULL, "Window class registration has failed!", "Error:", MB_OK | MB_ICONERROR);
return 0;
}
hWnd = CreateWindow ("1", "Win32 Animation Testing", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
hInstance, NULL);
if( ! hWnd )
{
MessageBox (NULL, "Window creation has failed!", "Error:", MB_OK | MB_ICONERROR);
return 0;
}
ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );
while( GetMessage( &uMsg, NULL, 0, 0 ) > 0 )
{
TranslateMessage( &uMsg );
DispatchMessage ( &uMsg );
}
return ( int ) uMsg.wParam;
}
No, that still works just fine when I tried your code on Windows 8, compiled with VS2012. A screenshot to prove it:
Notable is that your error checking is lacking, you don't pay attention to the return value of Animate_Open(). A FALSE return indicates that it could not open the .avi file. Many possible reasons, there's no better diagnostic from that function than "could not do it".
It was difficult to find a .avi file that it could handle, the control is stone-cold old and cannot handle but the simplest ones. In particular an .avi file that also has a audio track will not open, as documented by the MSDN Library. The test one I used was a very simple one I dug out of the Visual Studio image library, Animations/filecopy_16.avi.
So basic checks, after adding the error handling, is to ensure that the file is actually present in the same directory as your EXE and that it is a very simple .avi file that at least plays back in WMP.

Why does my Win32 application nearly crash my computer when I try rendering OpenGL to a static control?

I have a Win32 application with a static control that I want to render to using OpenGL. The problem is when I run the application, my computer comes to a screeching halt and more than once now I've had to hard-reboot it. It takes less than a second and it's really brutal. Most of my code here is ripped off of the internet or from my OpenGL bluebook. I have tried doing this several other ways, some with the same results and some with different but no more desirable results, including making the static control owner-draw, subclassing the static control, and just rendering to the control in it's parent's (the main window's) WM_PAINT message. I'm not even rendering any geometry yet, I just want to see the clear color. Most if not all of the resources I've found online either don't cover rendering to a control or using MFC instead of native Win32 API calls.
I have determined that it only happens because I am calling glClear(). If I don't call it, I don't experience the slow down, but I also don't see anything in my static control.
Some more information:
Visual Studio 2010 Ultimate
Windows SDK v7.0a
GLEW 1.7
nVidia Quadro 1600M with the latest drivers
Windows 7 x64 Ultimate
Here is my code:
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define GLEW_STATIC
#include <windows.h>
#include <gl\glew.h>
#include <gl\wglew.h>
#include <Uxtheme.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
//#define WIN32_LEAN_AND_MEAN
#define IDC_THE_BUTTON 9001
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
struct GlobalSection
{
HINSTANCE app;
HWND wnd;
HWND button;
HWND panel;
HWND text;
HGLRC glrc;
HDC fdc;
} g;
bool initWindow(int cmdShow);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
void Init(HWND wnd);
void Render();
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow)
{
g.app = hInst;
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(iccex);
iccex.dwICC = ICC_BAR_CLASSES|ICC_COOL_CLASSES|ICC_LISTVIEW_CLASSES|ICC_PROGRESS_CLASS|ICC_STANDARD_CLASSES|ICC_TAB_CLASSES;
InitCommonControlsEx(&iccex);
initWindow(nCmdShow);
MSG m;
ZeroMemory(&m, sizeof(m));
while(m.message != WM_QUIT)
{
Render();
if(PeekMessage(&m, NULL, 0, 0, PM_REMOVE) && !IsDialogMessage(g.wnd, &m))
{
TranslateMessage(&m);
DispatchMessage(&m);
}
}
}
bool initWindow(int cmdShow)
{
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.lpszClassName = _T("Window Party");
wc.hInstance = g.app;
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.hIcon = LoadIcon(g.app, MAKEINTRESOURCE(IDI_ICON2));
wc.hIconSm = wc.hIcon;
RegisterClassEx(&wc);
g.wnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Window Party"), _T("Window Party"), WS_SYSMENU|WS_CLIPCHILDREN|WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 1280, 800, NULL, NULL, g.app, NULL);
ShowWindow( g.wnd, cmdShow ); // technically should be nCmdShow
return true;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_CREATE:
Init(hwnd);
return DefWindowProc(hwnd, message, wparam, lparam);
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
{
int wmId = LOWORD(wparam);
int wmEvent = HIWORD(wparam);
switch(wmId)
{
case IDM_FILE_CLOSE:
PostQuitMessage(0);
break;
case IDOK:
case IDC_THE_BUTTON:
{
MessageBox(hwnd, _T("You have pressed the button!"), _T("Congraturation"), MB_OK);
}
break;
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
}
break;
case WM_KEYDOWN:
{
TCHAR buff[64] = {0};
wsprintf(buff, _T("Key Pressed: 0x%X"), (unsigned)wparam);
MessageBox(hwnd, buff, _T("YOYOYO"), MB_OK);
break;
}
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
return 0;
}
void Init(HWND wnd)
{
//Creating controls
RECT cr;
GetClientRect(wnd, &cr);
g.panel = CreateWindow(_T("STATIC"), NULL, WS_CHILDWINDOW|WS_VISIBLE|CS_OWNDC|CS_VREDRAW|CS_HREDRAW, 0, 0, cr.right, cr.bottom-26, wnd, NULL, g.app, NULL);
g.button = CreateWindow(_T("BUTTON"), _T("The Button"), WS_CHILDWINDOW|BS_DEFPUSHBUTTON|WS_VISIBLE, cr.right-160, cr.bottom-26, 160, 26, wnd, (HMENU)IDC_THE_BUTTON, g.app, NULL);
g.text = CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), NULL, WS_CHILDWINDOW|ES_LEFT|WS_VISIBLE, 0, cr.bottom-26, cr.right-160, 26, wnd, NULL, g.app, NULL);
//Setting fonts
HFONT hf = NULL;
hf = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(g.button, WM_SETFONT, (WPARAM)hf, TRUE);
SendMessage(g.text, WM_SETFONT, (WPARAM)hf, TRUE);
//Creating wgl context
g.fdc = GetDC(g.panel);
PIXELFORMATDESCRIPTOR pfd = {0};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 16;
pfd.cStencilBits = 8;
SetPixelFormat(g.fdc, 1, &pfd);
g.glrc = wglCreateContext(g.fdc);
wglMakeCurrent(g.fdc, g.glrc);
RECT pcr;
GetClientRect(g.panel, &pcr);
glViewport(0, 0, pcr.right, pcr.bottom);
glewInit();
glClearColor(0.0, 0.0, 0.0, 1.0);
UpdateWindow(wnd);
}
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SwapBuffers(g.fdc);
}
You must not call Render() for every single window message! Only call Render() for WM_PAINT messages.
This sounds like a memory leak somewhere. The computer will come to a screeching stop if the PF usage gets too high.
Open up your task manager and look at the PF Usage before and then again during running the program. If it jumps up .5GB or more and keeps climbing then you've got a memory leak on your hands.
If it behaves in the manner described above the most likely culprit is that you are either making a new object (or texture) multiple times causing Windows to need to allocate more PF space for you, or you could have your VSYNC turned off.
I probably don't have to tell you what happens with a memory leak, but with the VSYNC turned off the program is going to try to run as fast as the CPU lets it. It will max out your CPU and it will do it fast.
Hope this helps.

Resources