OpenGL, WinAPI | garbage values to unicode(I think, L"") string - c++

I want to try and learn OpenGL, I know C++ and I found a site with C++/OpenGL tutorials, this site also teaches a few things about WinAPI,bcs "our" programms are going to be Windows applications. In this tutorial it has the code of "our" first Windows application. The code (it doesn't compile):
/* Trim fat from windows*/
#define WIN32_LEAN_AND_MEAN
#pragma comment(linker, "/subsystem:windows")
/* Pre-processor directives*/
#include "stdafx.h"
#include <windows.h>
/* Windows Procedure Event Handler*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
/* Device Context*/
HDC hDC;
/* Text for display*/
char string[] = "Hello, World!";
/* Switch message, condition that is met will execute*/
switch(message)
{
/* Window is being created*/
case WM_CREATE:
return 0;
break;
/* Window is closing*/
case WM_CLOSE:
PostQuitMessage(0);
return 0;
break;
/* Window needs update*/
case WM_PAINT:
hDC = BeginPaint(hwnd,&paintStruct);
/* Set txt color to blue*/
SetTextColor(hDC, COLORREF(0x00FF0000));
/* Display text in middle of window*/
TextOut(hDC,150,150,string,sizeof(string)-1);
EndPaint(hwnd, &paintStruct);
return 0;
break;
default:
break;
}
return (DefWindowProc(hwnd,message,wParam,lParam));
}
/* Main function*/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX windowClass; //window class
HWND hwnd; //window handle
MSG msg; //message
bool done; //flag saying when app is complete
/* Fill out the window class structure*/
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = "MyClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
/* Register window class*/
if (!RegisterClassEx(&windowClass))
{
return 0;
}
/* Class registerd, so now create window*/
hwnd = CreateWindowEx(NULL, //extended style
"MyClass", //class name
"A Real Win App", //app name
WS_OVERLAPPEDWINDOW | //window style
WS_VISIBLE |
WS_SYSMENU,
100,100, //x/y coords
400,400, //width,height
NULL, //handle to parent
NULL, //handle to menu
hInstance, //application instance
NULL); //no extra parameter's
/* Check if window creation failed*/
if (!hwnd)
return 0;
done = false; //initialize loop condition variable
/* main message loop*/
while(!done)
{
PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE);
if (msg.message == WM_QUIT) //check for a quit message
{
done = true; //if found, quit app
}
else
{
/* Translate and dispatch to event queue*/
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
It didn't compile, it had a few errors so I changed it a bit:
/* Trim fat from windows*/
#define WIN32_LEAN_AND_MEAN
#pragma comment(linker, "/subsystem:windows")
/* Pre-processor directives*/
#include <tchar.h> //couldn't find stdafx.h
#include <windows.h>
/* Windows Procedure Event Handler*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
/* Device Context*/
HDC hDC;
/* Text for display*/
wchar_t string[] = L"F*CK!!!! It doesn't work, why am I getting Kanji? WTF\0"; // fixed error: char not compatible, char -> wchar_t
/* Switch message, condition that is met will execute*/
switch (message)
{
/* Window is being created*/
case WM_CREATE:
return 0;
break;
/* Window is closing*/
case WM_CLOSE:
PostQuitMessage(0);
return 0;
break;
/* Window needs update*/
case WM_PAINT:
hDC = BeginPaint(hwnd, &paintStruct);
/* Set txt color to blue*/
SetTextColor(hDC, COLORREF(0x00FF0000));
/* Display text in middle of window*/
TextOut(hDC, 150, 150, string, sizeof(string) - 1);
EndPaint(hwnd, &paintStruct);
return 0;
break;
default:
break;
}
return (DefWindowProc(hwnd, message, wParam, lParam));
}
/* Main function*/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX windowClass; //window class
HWND hwnd; //window handle
MSG msg; //message
bool done; //flag saying when app is complete
/* Fill out the window class structure*/
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"MyClass"; // fixed error: char* not compatible with LPCWSTR
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
/* Register window class*/
if (!RegisterClassEx(&windowClass))
{
return 0;
}
/* Class registerd, so now create window*/
hwnd = CreateWindowEx(NULL, //extended style
L"MyClass", //class name | fixed error: char* not compatible with LPCWSTR
L"A Real Win App", //app name | fixed error: char* not compatible with LPCWSTR
WS_OVERLAPPEDWINDOW | //window style
WS_VISIBLE |
WS_SYSMENU,
100, 100, //x/y coords
400, 400, //width,height
NULL, //handle to parent
NULL, //handle to menu
hInstance, //application instance
NULL); //no extra parameter's
/* Check if window creation failed*/
if (!hwnd)
return 0;
done = false; //initialize loop condition variable
/* main message loop*/
while (!done)
{
PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
if (msg.message == WM_QUIT) //check for a quit message
{
done = true; //if found, quit app
}
else
{
/* Translate and dispatch to event queue*/
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
Now it compiles, but, I get this:
The "F*CK!!!! it doesn't work, why am I getting Kanji, WTF" is correct(Forgive me if it is not Kanji)
Thank you for listening(reading actually) to my problems

You need to replace this:
TextOut(hDC, 150, 150, string, sizeof(string) - 1);
with this:
TextOut(hDC, 150, 150, string, wcslen(string));
sizeof (string) is in bytes, not characters.
Also, please don't spam language tags. Just pick the one(s) that are relevant.

The last parameter of TextOut() takes a character count, but you are passing it a byte count instead.
In the original code, the string array used char characters, and sizeof(char) is 1 byte, so the two counts were the same numeric value. But you changed the code to use wchar_t characters instead, and on Windows sizeof(wchar_t) is 2 bytes.
So, by using TextOut(..., string, sizeof(string) - 1) with a wchar_t string, you are telling TextOut() that there are 2 times as many wchar_ts in the string array as there really are, and thus TextOut() goes out of bounds of the string array printing out random garbage from surrounding memory (consider yourself lucky the code didn't just crash outright from accessing memory it didn't own).
If you are going to use sizeof() in this manner, then to get the correct array element count, you need to divide the array's byte size by its element's byte size, eg:
TextOut(..., string, (sizeof(string) / sizeof(string[0])) - 1)
You can replace that with the _countof() macro in Visual Studio (or equivalent in other compilers), eg:
TextOut(..., string, _countof(string) - 1)
In C++11 and later, you should use std::size() instead, eg:
TextOut(..., string, std::size(string) - 1)
Note that if the string array is ever replaced with a wchar_t* pointer in the future, these solutions will not work anymore. The sizeof() solution will still compile but will not produce the correct result. But the _countof() and std::size() solutions will fail to compile, which is a good thing. Then you will know that you need to replace it with a more appropriate solution, like lstrlenW(), std::wstring::size(), etc.

You're using sizeof(string). That's the number of bytes, not the number of characters. Since you're using C++, use std::wstring::size().

Related

Switching between two windows in C++ win32

i'm building an app in pure c++/win32. it contains two separately used windows. when i switch to 2nd window first time, it shows perfectly. closing it and reverting to first window works fine too, but when i try to switch to 2nd window again, it never shows. i wonder, what am i doing wrong?
#include <windows.h>
#include <windowsx.h>
HWND mainWnd, subWnd;
HINSTANCE hInst;
HWND btnShowSubWindow;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CREATE:{
btnShowSubWindow = CreateWindow("button", "Show 2nd window", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
50,50,150,20,
hwnd,(HMENU)1000, hInst, NULL);
break;
}
case WM_COMMAND:{
switch(LOWORD(wParam)){
case 1000:{
ShowWindow(mainWnd, SW_HIDE);
ShowWindow(subWnd, SW_SHOW);
break;
}
}
break;
}
case WM_CLOSE:{
if (MessageBox(hwnd, "Really quit?", "My application", MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}
break;
}
/* Upon destruction, tell the main thread to stop */
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
/* All other messages (a lot of them) are processed using default procedures */
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK SubWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CLOSE:{
CloseWindow(hwnd);
ShowWindow(mainWnd, SW_SHOW);
break;
}
/* All other messages (a lot of them) are processed using default procedures */
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
void CreateMainWnd(){
WNDCLASSEX wc; /* A properties struct of our window */
/* zero out the struct and set the stuff we want to modify */
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = MainWndProc; /* This is where we will send messages to */
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "MainWindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return;
}
mainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,wc.lpszClassName,"Main window",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,hInst,NULL);
if(mainWnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return;
}
}
void CreateSubWnd(){
WNDCLASSEX wc; /* A properties struct of our window */
/* zero out the struct and set the stuff we want to modify */
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = SubWndProc; /* This is where we will send messages to */
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "SubWindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return;
}
subWnd = CreateWindowEx(WS_EX_CLIENTEDGE,wc.lpszClassName,"Secondary window",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,hInst,NULL);
if(subWnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return;
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg; /* A temporary location for all messages */
hInst = hInstance;
CreateMainWnd();
CreateSubWnd();
ShowWindow(mainWnd, nCmdShow);
ShowWindow(subWnd, SW_HIDE);
/*
This is the heart of our program where all input is processed and
sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
this loop will not produce unreasonably high CPU usage
*/
while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
TranslateMessage(&msg); /* Translate key codes to chars if present */
DispatchMessage(&msg); /* Send it to WndProc */
}
return msg.wParam;
}
i'm using Dev-C++ 5.11.
Addition #1:
i read the answer and i changed MainWndProc's WM_COMMAND handler a bit. now it looks like that:
switch(LOWORD(wParam)){
case 1000:{
ShowWindow(mainWnd, SW_HIDE);
if(subWnd!=NULL)
ShowWindow(subWnd, SW_SHOW);
else
ShowWindow(hwnd, SW_SHOW);
break;
}
i also added a WM_DESTROY handler to SubWndProc:
case WM_DESTROY:{
return 1;
break;
}
if subWnd was destroyed then mainWnd should reappear but it doesn't. i guess that something screws up the contents of subWnd after it hides.
OK, you're calling CloseWindow which minimizes the subwindow. To restore a minimized window, you need to use SW_RESTORE rather than SW_SHOW.
The default action when a user closes a window (by pressing the × in the upper right or through the taskbar) is, that it get's destroyed and it's HWND turns invald. ShowWindow can hide and show existing windows, but it can't resurrect the "dead".
What you can do however is, that you implement a handler for the WM_CLOSE message that hides the window, instead of destroying it. But you must make sure, that once all windows are hidden you actually quit the program, or some other way give the user to interact.
However creating windows is kind of cheap, so the better solution is, to let the windows get destroyed and just to create a new window as replacement.

Win32 C++: Creation and Calling method from separate C++ file

I'm new to win32 c++ programming and I need help figuring out how to include methods in other files in my Win32 c++ application. I want to write methods in other files and include them in my code. I want to have a separate file, openFile, containing a method that is called from OpenWordGUI will pass back the file path. Is this possible?
Currently my code looks like the following:
// OpenWordDocGUI.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "OpenWordDocGUI.h"
#define MAX_LOADSTRING 100
//Defines for buttons
#define TSP_BUTTON 1
#define PCM_BUTTON 2
#define GO_BUTTON 3
//Defines Text boxes
#define TSP_BOX 101
#define PCM_BOX 102
//For text box
HWND TSPBox;
HWND PCMBox;
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
//Globals for
TCHAR szFilters[] = _T("Input files (*.*)\0*.*\0\0");
TCHAR szFilePathName[_MAX_PATH] = _T("");
//Store file paths in separate variables
TCHAR TSPFilePath[_MAX_PATH] = _T("");
TCHAR PCMFilePath[_MAX_PATH] = _T("");
int textBoxStat = 0;
TCHAR szInputBoxPathName[_MAX_PATH];
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_OPENWORDDOCGUI, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENWORDDOCGUI));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENWORDDOCGUI));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_OPENWORDDOCGUI);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//Default
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
// Fill the OPENFILENAME structure for use in
// TSP/PCM buttons
OPENFILENAME ofn = {0};
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = szFilters;
ofn.lpstrFile = szFilePathName; // This will hold the file name
ofn.lpstrDefExt = _T("dat");
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrTitle = _T("Open File");
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
//////
switch (message)
{
case WM_CREATE:
//TSP MOA Button Creation
//Will bring up open file dialog when clicked
CreateWindow(TEXT("button"), TEXT("TSP MOA"),
WS_VISIBLE | WS_CHILD,
10, 10, 80, 25,
hWnd, (HMENU) TSP_BUTTON, NULL, NULL
);
//Window to show Selected TSP MOA
TSPBox = CreateWindow(TEXT("edit"), TEXT(""),
WS_BORDER | WS_CHILD | WS_VISIBLE,
100, 10, 400, 25,
hWnd, (HMENU) TSP_BOX,
NULL, NULL);
//PCM File Button Creation
//Will bring up open file dialog when clicked
CreateWindow(TEXT("button"), TEXT("PCM File"),
WS_VISIBLE | WS_CHILD,
10, 50, 80, 25,
hWnd, (HMENU) PCM_BUTTON, NULL, NULL
);
//Text box for PCM file creation
PCMBox = CreateWindow(TEXT("edit"), TEXT(""),
WS_BORDER | WS_CHILD | WS_VISIBLE,
100, 50, 400, 25,
hWnd, (HMENU) PCM_BOX,
NULL, NULL);
//Execute compare button
CreateWindow(TEXT("button"), TEXT("Compare"),
WS_VISIBLE | WS_CHILD,
10, 90, 80, 25,
hWnd, (HMENU) GO_BUTTON, NULL, NULL
);
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case TSP_BUTTON:
//TSP Button clicked
//Open file dialog to select TSP MOA - done
//
TSPFilePath = openFile(TSP);
break;
case PCM_BUTTON:
//PCM Button clicked
//Open file dialog to select PCM file
PCMFilePath = openFile(PCM);
break;
case GO_BUTTON:
//Execute the following
//Read TSP MOA
//TSP MOA to Excel
//PCM to Excel
//compare TSP Excel to PCM
//Do data check
//Get data from TSP Text box
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Openfile would look something like:
#include <Commdlg.h>
#include <windows.h>
TCHAR* openFile(systemSel)
{
if (systemSel == "TSP")
{
//Set filter for openfile to word docs
} else {
//set filter for openfile to excel files
}
OPENFILENAME ofn ;
TCHAR szFile[MAX_PATH] ;
// open a file name
ZeroMemory( &ofn , sizeof( ofn));
ofn.lStructSize = sizeof ( ofn );
ofn.hwndOwner = NULL ;
ofn.lpstrFile = szFile ;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof( szFile );
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex =1;
ofn.lpstrFileTitle = NULL ;
ofn.nMaxFileTitle = 0 ;
ofn.lpstrInitialDir=NULL ;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
GetOpenFileName( &ofn )
return szFile
}
You need to have a header file which declares function openFile. Including this header in OpenWordDocGUI.cpp does the job.
There are a lot of tutorials on the internet showing how to write own header files to access functions within another .cpp file.
For example try this one: http://www.learncpp.com/cpp-tutorial/19-header-files

WinMain/Win32 Window not displaying, but shows up in Processes tab of Task Manager

I'm a newbie to c++, and I'm stuck on displaying the window. I'm not getting any errors, but my Window is not displaying on the desktop. When I open the task manager, it appears under the 'Proccesses' tab. I haven't been finding any solutions to this problem, so any help is appreciated. Thanks! :)
**Note: I'm using Microsoft Visual Studio 2012
**Note: Not exactly a newbie to c++, but more to creating a win32 application
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
static TCHAR WindowClass[] = L"Window";
LRESULT CALLBACK WindowProc(
HWND WinH,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
switch (Msg)
{
PAINTSTRUCT pntStruct;
static HDC hdc;
case WM_PAINT:
{
BeginPaint(
WinH,
&pntStruct
);
TextOut(hdc,
5, 5,
L"Hello, World!", _tcslen(L"Hello, World!"));
//pntStruct.rcPaint
EndPaint(
WinH,
&pntStruct
);
} break;
case WM_SIZE:
{
} break;
case WM_MOVE:
{
} break;
case WM_DESTROY:
{
} break;
case WM_CLOSE:
{
} break;
default:
{
return DefWindowProc(WinH, Msg, wParam, lParam);
} break;
case WM_ACTIVATEAPP:
{
if (WM_ACTIVATEAPP)
{
OutputDebugStringA("WM_ACTIVEAPP->TRUE");
}
else
{
OutputDebugStringA("WM_ACTIVEAPP->FALSE");
}
} break;
}
return 0;
};
int WINAPI WinMain(
HINSTANCE Window,
HINSTANCE PrevInstance,
LPSTR Cmd,
int CmdShow
)
{
WNDCLASSEX wclass;
//wclass.cbSize = sizeof(WNDCLASS);
wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wclass.lpfnWndProc = WindowProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = Window;
//wclass.hIcon; TODO: CREATE ICON
//wclass.hCursor;
//wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = (LPCTSTR)WindowClass;
// HICON hIconSm;
RegisterClassEx(&wclass);
HWND CreateWin = CreateWindow(
WindowClass,
L"NAME OF WINDOW",
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
0,
0,
Window,
0
);
ShowWindow(CreateWin, CmdShow);
UpdateWindow(CreateWin);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
};
return 0;
};
There are lots of things wrong with this code.
You are declaring WindowClass as a TCHAR[], but initializing it with a wchar_t[]. Same thing with the lpString parameter of TextOut(). That will only work if UNICODE is defined for the project, otherwise you will get a compiler error. When you use TCHAR, you need to wrap string literals with the TEXT() macro so they use the correct character type. Otherwise, stop using TCHAR and just use Unicode APIs for everything. You only need to use TCHAR if your code needs to support both ANSI (Win9x/ME) and Unicode (NT4+) compilations. Nobody really supports Win9x/Me anymore, so new code should focus on just Unicode APIs.
You are not zeroing the contents of the WNDCLASSEX structure, so all of the fields that you have intentionally commented out and not assigned values to (most importantly, the cbSize field) will contain random values from the stack. That is likely to cause RegisterClassEx() to fail, which you are not checking for. To avoid this problem, ALWAYS zero out API structures before using them. This is especially important for structures that grow in size over time (when newer Windows releases introduce new structure fields). Such structures typically have a cbSize field so the API knows which version of the structure you are using, so you must provide an accurate value. And you need to zero out any unused fields so you do not get unexpected behavior from the API.
You are not checking if CreateWindow() fails, such as a side effect of RegisterClassEx() failing.
Your WindowProc() is supposed to pass unhandled messages to DefWindowProc(), but you are not doing that. Most of your case blocks are simply discarding messages so Windows cannot process them. Is that what you really want? I doubt it. In particular, the default behavior of DefWindowProc() for WM_CLOSE is to destroy the window, triggering the WM_DESTROY message.
Your WM_DESTROY handler is not calling PostQuitMessage() to put a WM_QUIT message into the calling thread's message queue so GetMessage() can return 0 to break your message loop and let the app exit.
Your WM_PAINT handler is not using the HDC that BeginPaint() provides to you, you are drawing using an uninitialized HDC variable.
With all of that said, try something more like this:
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h> // Or: remove this
static TCHAR WindowClass[] = TEXT("Window");
// or: static WCHAR WindowClass[] = L"Window";
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
static const TCHAR* HelloWorld = TEXT("Hello, World!");
// or: const WCHAR* HelloWorld = L"Hello, World!";
PAINTSTRUCT pntStruct = {0};
HDC hdc = BeginPaint(hWnd, &pntStruct);
TextOut(hdc, 5, 5, HelloWorld, _tcslen(HelloWorld));
// or: TextOutW(hdc, 5, 5, HelloWorld, lstrlenW(HelloWorld));
EndPaint(hWnd, &pntStruct);
break;
}
case WM_SIZE:
{
//...
break;
}
case WM_MOVE:
{
//...
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
case WM_CLOSE:
{
//...
break;
}
case WM_ACTIVATEAPP:
{
if (WM_ACTIVATEAPP)
{
OutputDebugString(TEXT("WM_ACTIVEAPP->TRUE"));
// or: OutputDebugStringW(L"WM_ACTIVEAPP->TRUE");
}
else
{
OutputDebugString(TEXT("WM_ACTIVEAPP->FALSE"));
// or: OutputDebugStringW(L"WM_ACTIVEAPP->FALSE");
}
break;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wclass = {0}; // Or: WNDCLASSEXW
wclass.cbSize = sizeof(wclass);
wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wclass.lpfnWndProc = &WindowProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = NULL; // TODO: CREATE ICON
wclass.hCursor = NULL;
wclass.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = WindowClass;
wclass.hIconSm = NULL;
if (!RegisterClassEx(&wclass)) // Or: RegisterClassExW()
{
// error! Use GetLastError() to find out why...
return 0;
}
HWND hCreateWin = CreateWindow( // Or: CreateWindowW()
WindowClass,
TEXT("NAME OF WINDOW"), // Or: L"NAME OF WINDOW"
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
0,
0,
hInstance,
0
);
if (!hCreateWin)
{
// error! Use GetLastError() to find out why...
return 0;
}
ShowWindow(hCreateWin, nCmdShow);
UpdateWindow(hCreateWin);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
};
return 0;
};

Dev C++ - Opaque Text On Transparent Frame

I am a beginner c++ graphics programmer and using dev c++ as IDE. I created a simple frame with textbox and a button and called DwmExtendFrameIntoClientArea from dwmapi.dll.
But the textbox and button show ugly transparent text. I want opaque text on textbox and button. I've searched all around but found answers for .NET c++ and not dev c++. So please help me dealing with this matter using dev c++. Efforts will be appreciated.
Here's the code:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <uxtheme.h>
HWND tb;
HWND btn;
typedef struct _DWM_BLURBEHIND
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
HINSTANCE DLL = LoadLibrary("dwmapi.dll");
typedef HRESULT (*_DwmExtendFrameIntoClientArea)(HWND hwnd,MARGINS* margins);
_DwmExtendFrameIntoClientArea DwmExtendFrameIntoClientArea = (_DwmExtendFrameIntoClientArea)GetProcAddress(DLL,"DwmExtendFrameIntoClientArea");
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CREATE: {
ShowWindow(GetConsoleWindow(),SW_HIDE);
MARGINS margins = {-1,-1,-1,-1};
DwmExtendFrameIntoClientArea(hwnd,&margins);
tb = CreateWindow("EDIT","Text",WS_CHILD | WS_VISIBLE,5,5,574,30,hwnd,NULL,NULL,NULL);
btn = CreateWindow("BUTTON","Button",WS_CHILD | WS_VISIBLE,5,50,80,30,hwnd,NULL,NULL,NULL);
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) {
WNDCLASSEX wc; /* A properties struct of our window */
HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
MSG Msg; /* A temporary location for all messages */
/* zero out the struct and set the stuff we want to modify */
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOWTEXT);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_WINDOWEDGE,"WindowClass","Frame",WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
600, /* width */
350, /* height */
NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
/*
This is the heart of our program where all input is processed and
sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
this loop will not produce unreasonably high CPU usage
*/
while(GetMessage(&Msg, NULL, 0, 0) > 0) { /* If no error is received... */
TranslateMessage(&Msg); /* Translate key codes to chars if present */
DispatchMessage(&Msg); /* Send it to WndProc */
}
return (int) Msg.wParam;
}

During resize OpenGL swapbuffers stalls

I am currently working on an OpenGL win32 project converting the standard win32 to C++ classes. During the initial implementation I ran into an issue where when the window is resized the frame freezes and the window changes size very slowly, jumping from one size to the next. When the window is finished resizing there is noticeable hesitation before the window updates the drawing surface.
I am using a WM_TIMER to update the display as frequently as possible. During 'normal' operation the program clears the screen, slowly updating the red component to visually show a change in the surface drawing. Given the extremely simple design of the test I can't imagine that the openGL code is the problem during a resize event. I did test to see if manually resizing the window by catching the mouse button down and calling setwindowpos with adjusted values would cause the same behavior and it did. If I kept the size the same and called SetWindowPos the screen didn't stall though. This leads me to believe that something in the resize handling code is locking the HDC in some way preventing the swapbuffers from performing at speed. Possibly waiting on a multithread lock somewhere in the Win32 resize code.
Below is a small program that exhibits the exact same behavior as the larger program.
Only external lib being used is opengl32.lib.
#include "stdafx.h"
#include "OpenGLTest.h"
#include <gl\GL.h>
#define MAX_LOADSTRING 100
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
ATOM MyRegisterClass(HINSTANCE hInstance,LPCTSTR strClassName,WNDPROC wndProc,HBRUSH brBackground);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND _hWnd;
HDC _hDC;
HGLRC _glRC;
BOOL DrawWindow();
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_OPENGLTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance,szWindowClass,WndProc,NULL);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGLTEST));
// Main message loop:
bool bRun=true;
while (bRun)
{
if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message==WM_QUIT)
{
break;
}
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance,LPCTSTR strClassName,WNDPROC wndProc,HBRUSH brBackground)
{
WNDCLASSEX wcex;
//Register Main Window Class
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW ;
wcex.lpfnWndProc = wndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = brBackground;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = strClassName;
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!_hWnd)
{
return FALSE;
}
_hDC=GetDC(_hWnd);
if (_hDC!=nullptr)
{
//Create OpenGL 3.2 context
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
32, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, //Number of bits for the depthbuffer
8, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int nPixelFormat=ChoosePixelFormat(_hDC,&pfd);
SetPixelFormat(_hDC,nPixelFormat,&pfd);
if ((_glRC=wglCreateContext(_hDC))!=nullptr)
{
//Make Context Current
wglMakeCurrent(_hDC,_glRC);
}
}
ShowWindow(_hWnd, nCmdShow);
UpdateWindow(_hWnd);
SetTimer(_hWnd, 0, 1, NULL);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_TIMER:
DrawWindow();
break;
case WM_ERASEBKGND:
return TRUE;
case WM_PAINT:
BeginPaint(_hWnd,&ps);
EndPaint(_hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
float fRed=0.0f;
BOOL DrawWindow()
{
RECT rc;
GetClientRect(_hWnd,&rc);
HDC hDC=GetDC(_hWnd);
if ((hDC!=nullptr)&&(_glRC!=nullptr))
{
//Print Client Data to Window Title for debugging
TCHAR strTitle[MAX_LOADSTRING];
wsprintf(strTitle,L"%d, %d, %d, %d",rc.left,rc.top,rc.right,rc.bottom);
SetWindowText(_hWnd,strTitle);
wglMakeCurrent(hDC,_glRC);
glViewport(rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top));
glClearColor(fRed,1.0f,0.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT);
SwapBuffers(hDC);
fRed+=0.1;
if (fRed>1.0f) fRed=0.0f;
ReleaseDC(_hWnd,hDC);
}
return TRUE;
}
EDIT: The problem is a hardware issue not software. I moved over to another system and the issue is not there. Thank you for your assistance.