Dev C++ - Opaque Text On Transparent Frame - dev-c++

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;
}

Related

CreateWindowsEx fails when creating window

I am new to win32 API GUI programming in C++. When the program is compiled and executed, It always fails at CreateWindowsEx. Sorry but this only what I can explain at this moment.
Aside from that, It passes the window registration, which is good. But from the time Windows Creation executed, it always return NULL.
Here's my C++ code:
#include <windows.h>
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow){
//MessageBox(NULL, "Hello ", " H", MB_OK);
WNDCLASSEX wc = {0};
//memset(&wc,0,sizeof(wc));
//wc.cbSize = sizeof(WNDCLASSEX);
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WindowProcedure; /* 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 = "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, "Error 1", " H", MB_OK);
return -1;
}
HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,hInst,NULL);
//returns 0x0
//return GetLastError();
if( hwnd == NULL){
MessageBox(NULL, "Error 2", " H", MB_OK);
return GetLastError();
}
MSG msg = {0};
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
return 0;
}
Please approach in the level of a novice, so it easy for me to understand what should be done.
The reason why the CreatewindowEx fails is because of DefWindowProcW should be DefWindowProc.
DefwindowProcW is used with CreateWindowW, but since it is using CreateWindowEx, DefWindowProc should be the correct one to use.

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

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().

Icon in Windows Explorer showing 2 different icons when using resource.rc

I'm trying to change the icon of my Windows application. I'm using the simple window code below and added a resource.h and resource.rc to the solution. I'm using a test.ico and a test2.ico-file which both contain 64x64, 32x32, 24x24 and 16x16 sizes.
The when I switch between icon and icon2 by simple changing this line TESTICON ICON "test.ico" to TESTICON ICON "test2.ico" in the .rc-file, the icons change accordingly in program header bar, taskbar and alt-tab view. But the icon in my windows explorer is acting totally strange. When I set the view to details,list or small I see the test.ico-icon, but for medium, large and extra large I see the test2.ico-icon, no matter what I set in the .rc-file. I'm totally lost here, which setting am I missing?
The 'resource.h'
#pragma once
#define TESTICON 1
and the 'resource.rc'
#include "resource.h"
TESTICON ICON "test.ico"
The simple windows source:
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASSEX wc = { };
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASS_NAME;
wc.hIcon = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(TESTICON), IMAGE_ICON,
::GetSystemMetrics(SM_CXICON),
::GetSystemMetrics(SM_CYICON), 0);
wc.hIconSm = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(TESTICON), IMAGE_ICON,
::GetSystemMetrics(SM_CXSMICON),
::GetSystemMetrics(SM_CYSMICON), 0);
RegisterClassEx(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
As pointed out by Jonathan Potter: Explorer has an icon cache; if it's showing the wrong icon you probably need to clear the cache.
http://leodavidson.blogspot.com/2011/05/clear-icon-cache-1001.html

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.

DirectX and C++

I am having trouble with the following CPP code: http://ideone.com/XZXZJ .
I am receiving the following errors:
(1) Warning 1 warning LNK4042: object specified more than once; extras ignored c:\Users\jabbott\documents\visual studio 2010\Projects\DirectX9_Tutorial\DirectX9_Tutorial\Debug\WinMain.obj 1
(2) Error 2 error LNK1561: entry point must be defined c:\Users\jabbott\documents\visual studio 2010\Projects\DirectX9_Tutorial\DirectX9_Tutorial\LINK
No Entry Point setting isn't set. I've tried to set this to WinMain with no luck.
// WinMain.h
#ifndef APP_HPP_
#define APP_HPP_
#include <Windows.h> // Windows API Library
#include <d3d9.h> // Include DirectX 9 Library
#include <d3d10_1.h> // Include DirectX 10 Library
#include <d3d11.h> // Include DirectX 11 Library
/* Global Functions */
// Handle any messages from MS Windows
LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
// Main Entry Point
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd);
/* Global Variables */
IDirect3D9 *g_pD3D; // DirectX 3D v9 Instance
IDirect3DDevice9 *g_pD3DDevice; // DX3D9: Representation of Graphics Card
LPCTSTR ClsName = "g_szInterfaceClass";
//IDirect3D10 *g_pD3D10; // DirectX 3D v10 Instance
//IDirect3DDevice10 *g_pD3DDevice10; // DX3D10: Representation of Graphics Card
//IDirect3D11 *g_pD3D11; // DirectX 3D v11 Instance
//IDirect3DDevice11 *g_pD3DDevice11; // DX3D11: Representation of Graphics Card
#define WINDOW_WIDTH 200
#define WINDOW_HEIGHT 200
/* Error Macro for Debugging */
//#define ERROR(msg) { MessageBox(NULL, msg, L"Error", MB_OK|MB_ICONEXCLAMATION); }
#endif // WINMAIN_H
WinMain.cpp:
// WinMain.cpp
#include "WinMain.h"
LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,
uMsg,
wParam,
lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); /* Predeclaration of WinProc() */
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
// The WNDCLASSEX structure contains window class information
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) 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 = ClsName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// rect structure to define the window dimensions
RECT rect;
rect.top = (long) 0;
rect.left = (long) 0;
rect.right = (long) WINDOW_WIDTH;
rect.bottom = (long) WINDOW_HEIGHT;
// Register the window to MS Windows
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// calculate the required size of the window rectangle, based on the desired size of the client rectangle
AdjustWindowRectEx( &rect,
WS_OVERLAPPEDWINDOW,
FALSE,
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);
// create the target window of the application
HWND hWindow = CreateWindowEx(NULL,
ClsName,
"Name of Window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0,
rect.right-rect.left,
rect.bottom-rect.top,
NULL, NULL,
hInstance,
NULL);
if (!hWindow)
{
DestroyWindow(hWindow);
UnregisterClass(ClsName, hInstance);
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWindow, SW_SHOW);
UpdateWindow(hWindow);
SetForegroundWindow(hWindow);
SetFocus(hWindow);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.hDeviceWindow = hWindow;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// Identify current version of Direct3D
g_pD3D =Direct3DCreate9(D3D_SDK_VERSION);
// Create the Direct3D Interface Device. Thisisanabstracted version of
if(FAILED(g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
MessageBox(NULL, "Failed to create Direct3D InterfaceDevice.", "Error!", MB_ICONEXCLAMATION | MB_OK);
}
/* Main Game Boot */
// Enter the message loop
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
// Clear the target render buffer black
g_pD3DDevice->Clear( 0,
0,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 0),
1.0f,
(DWORD) 0.0f);
// Send the buffer to the computer monitor
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
//Send any messages to WndProc function
TranslateMessage(&msg);
DispatchMessage(&msg);
}
g_pD3D->Release();
return 1;
}
Your first problem can be solved by deleting this line:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); /* Predeclaration of WinProc() */
You already have the implementation of the function directly above it. You only need the above if the implementation of the function occurs after the point the function is called or the implementation is in a different translation unit (source file). Generally, try to avoid the 'predeclaration' of functions if you can, use the function itself as the declaration, it will reduce the amount of maintenance required.
The second problem might be because you are compiling a console application (entry point main) rather than a windows application (entry point WinMain).