How to create fully transparent window which has not transparent content? - c++

I have tried this:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
case WM_MOVE:
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
}
case WM_CTLCOLORSTATIC:
{
HDC hdc = (HDC) wParam;
SetBkMode (hdc, TRANSPARENT);
return (LRESULT)(GetStockObject(NULL_BRUSH));
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int main()
{
WNDCLASSEX wc;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(GetStockObject(NULL_BRUSH));
wc.lpszMenuName = NULL;
wc.lpszClassName = L"MY CLASS";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
HWND hwnd = CreateWindowEx(0, L"MY CLASS", NULL, WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL);
HWND child = CreateWindowEx(0, L"STATIC", L"Text", WS_VISIBLE | WS_CHILD , 50, 50, 50, 50, hwnd, NULL, NULL, NULL);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
It creates window, which looks transparent, because it shows the same as on screen, however after moving window main window background stays the same. I want to ask, where the problem may be.
P.S. it is just test code, so, please, do not write advices not suited with my question.
Thanks.
EDIT: I want this because I'm going to make some helpers for users who don't know how to do some stuff. Result should be something like regular some program view with come spots marked, what means press here, when here, after that here and etc.

I think you start point should be with taking a look on Layered Windows
http://msdn.microsoft.com/en-us/library/ms997507.aspx
it is most common way for playing with custom shape and (semi)transparent windows.
UPD. There is also old API for making custom shaped windows:
int SetWindowRgn( HWND hWnd, HRGN hRgn, BOOL bRedraw );

Related

AnimateWindow not calling WM_PAINT

I need to animate the display of the rendered window, I have a WM_PRINTCLIENT and WM_PAINT event, but the window is not rendered during the animation, only if RedrawWindow is used after the animation is shown
WNDCLASSW Wcc;
MSG Msg;
Wcc.style = CS_HREDRAW | CS_VREDRAW;
Wcc.lpfnWndProc = &this->_ChildWndProc;
Wcc.cbClsExtra = 0;
Wcc.cbWndExtra = 0;
Wcc.hInstance = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
hInst_ = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
Wcc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Wcc.hCursor = LoadCursor(NULL, IDC_ARROW);
Wcc.hbrBackground = reinterpret_cast<HBRUSH> (CreateSolidBrush(RGB( 255, 255, 255)));
Wcc.lpszMenuName = NULL;
Wcc.lpszClassName = className;
this->className = className;
this->hParent = hWnd;
this->text = text;
this->title = title;
//this->title = title;
windowW = 450;
windowH = 300;
hChild = CreateWindowExW(0, Wcc.lpszClassName, 0, WS_POPUP | WS_MINIMIZEBOX, x, y,
windowW, windowH, hWnd, NULL, (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE), NULL);
loadResources(hChild);
SetWindowLongPtrW(hChild, GWLP_USERDATA, (LONG)this);
//SetTransparency(hChild, 0x0f);
//ShowWindow(hChild, SW_SHOW);
AnimateWindow(hChild, 1000, AW_ACTIVATE | AW_BLEND);
PAINT:
case WM_PAINT:
{
Paint(hDlg);
break;
}
case WM_PRINTCLIENT:
{
PaintA(hDlg);
break;
}
Paint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Graphics graphics(hdc);
Image image(L"g:\\_project\\image viewer\\ipcamera.jpg");
graphics.DrawImage(&image, 0, 0);
EndPaint(hwnd, &ps);
}
PaintA(HWND hwnd)
{
HDC hdc = GetDC(hwnd);
Graphics graphics(hdc);
Image image(L"g:\\_project\\image viewer\\ipcamera.jpg");
graphics.DrawImage(&image, 0, 0);
}
enter image description here
I have adopted your code, so that I can run it in isolation. I do get debug output WM_PRINTCLIENT during animation.
void foo(HINSTANCE hInst, HWND hParent) {
static const wchar_t* className = L"myClassName";
WNDCLASSW Wcc = {};
MSG Msg;
Wcc.style = CS_HREDRAW | CS_VREDRAW;
Wcc.lpfnWndProc = ChildWndProc;
Wcc.cbClsExtra = 0;
Wcc.cbWndExtra = 0;
Wcc.hInstance = hInst;
Wcc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Wcc.hCursor = LoadCursor(NULL, IDC_ARROW);
Wcc.hbrBackground = CreateSolidBrush(RGB(255, 0, 255));
Wcc.lpszMenuName = NULL;
Wcc.lpszClassName = className;
RegisterClassW(&Wcc);
HWND hChild = CreateWindowW(className, nullptr, WS_POPUP | WS_MINIMIZEBOX, 100, 200, 300, 400, nullptr, nullptr, hInst, nullptr);
AnimateWindow(hChild, 2000, AW_ACTIVATE | AW_BLEND);
}
And here is the window proc I used:
LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
::OutputDebugString(L"WM_PAINT\n");
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
case WM_PRINTCLIENT:
{
::OutputDebugString(L"WM_PRINTCLIENT\n");
HDC hdc = (HDC)wParam;
::MoveToEx(hdc, 10, 10, nullptr);
::LineTo(hdc, 100, 100);
}
case WM_ERASEBKGND:
{
::OutputDebugString(L"WM_ERASEBKGND\n");
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
NOTE:
For details, please see WM_PRINTCLIENT message
A window can process this message in much the same manner as WM_PAINT, except that BeginPaint and EndPaint need not be called (a device context is provided), and the window should draw its entire client area rather than just the invalid region.

Release version not working. Visual Studio C++

I have been programming a Window Application, for Windows, and in Debug mode everything works but when I want switch to release mode the Window that opens in Debug does not open. If I try it without Visual Studio a Task is visible in Task manager but no window.
To be honest right now I can't understand anything I have in this code, I understood it 3 months ago but due to circumstances I have not worked with this in the last months and this is my first window application and my first application I release.
The following code should be everything that handles the creation of the Window.
This program creates a simple user interface (WinAPI) for entering the desired button cycles.
The entered button cycles are then sent to the button test device via a bound TCP / IP client.
As soon as the push button test device is finished with the switching cycles, it transmits the incorrect switching and the task switching to the TCP / IP client.
As soon as the data has been received by the TCP / IP client, it is written to a .csv file by a CSV writer.
*/
#include <Windows.h>
#include <cassert>
#include <wingdi.h>
#include "TCP-IP-Client.h"
HWND hWndEdit;
wchar_t buffer[1024];
LRESULT CALLBACK MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_COMMAND:
if (LOWORD(wParam) == 10) {
GetWindowText(hWndEdit, buffer, 1024);
int Input[1] = { _wtoi(buffer) };
switch (TcpIpClient(Input)) {
case 10:
MessageBox(hWnd, L"Can't start Winsock" , L"Benachrichtigung", MB_ICONERROR);
break;
case 11:
MessageBox(hWnd, L"Can't create socket", L"Benachrichtigung", MB_ICONERROR);
break;
case 12:
MessageBox(hWnd, L"Can't connect to server", L"Benachrichtigung", MB_ICONERROR);
break;
case 13:
MessageBox(hWnd, L"Socket Error!", L"Benachrichtigung", MB_ICONERROR);
break;
}
}
break;
case WM_CTLCOLOREDIT:
if (hWndEdit == (HWND)lParam) {
HDC hdc = (HDC)wParam;
SetBkColor(hdc, RGB(211, 211, 211));
//SetTextColor(hdc, RGB(211, 211, 211)); // For diffrent color of latters
SetDCBrushColor(hdc, RGB(211, 211, 211));
return (LRESULT)GetStockObject(DC_BRUSH);
}
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 20, 20, L"Gewünschte Taster Zyklen Eingeben", strlen("Gewünschte Taster Zyklen Eingeben"));
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
HWND hWnd;
HWND hButton;
WNDCLASS wc;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MessageHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"WINAPITest";
assert(RegisterClass(&wc));
hWnd = CreateWindow(L"WINAPITest", L"WinAPI Tutorial", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, 0, 0, hInstance, 0);
hButton = CreateWindow(L"button", L"OK", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 40, 100, 200, 50, hWnd, (HMENU)10, hInstance, 0);
hWndEdit = CreateWindow(L"edit", NULL, WS_TABSTOP | WS_CHILD | WS_BORDER | WS_VISIBLE, 40, 48, 200, 50, hWnd, 0, 0, 0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (true) {
BOOL result = GetMessage(&msg, 0, 0, 0);
if (result > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
return result;
}
}
}
Two bugs:
As I called out in the comments, you are forgetting to invoke EndPaint and have a missing break statement. Fixing that and cleaning up your code so you don't have to duplicate the string:
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
const wchar_t* message = L"Gewünschte Taster Zyklen Eingeben";
TextOut(hdc, 20, 20, message, wcslen(message));
EndPaint(hWnd, &ps);
return 0; // THIS LINE ADDED
Bug #2 is that you are forgetting to invoke RegisterClass on your WNDCLASSEX structure. Also, it's usually a good idea to default initialize that struct (to zeros) in case you missed a field or wanted to skip it.
wc = {}; // zero-init THIS LINE ADDED
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MessageHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"WINAPITest";
RegisterClass(&wc); // THIS LINE ADDED
After I removed the TCP Client stuff, I got your program to somewhat work:
And for some style points, I cleaned up this:
while (true) {
BOOL result = GetMessage(&msg, 0, 0, 0);
if (result > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
return result;
}
}
To simply be this:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;

Message Box is not working inside WM_COMMAND! (WIN32 API)

I am new to Win32 API and trying to learn it. I was successful to create a window and it works perfectly.
I added a button to it and want to show a message box when clicked. The button works perfectly but the message box in WM_COMMAND does not appear at all and the code below message box does not get executed as well.
I have checked online for how to do it and it seems to work for them but not me.
Here is the code
#include <Windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
WNDCLASSEX wcex;
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("First Application");
HINSTANCE hInst;
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPSTR lpCmdLine,_In_ int nCmdShow)
{
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, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, _T("Call to Register Failed"), _T("Windows Desktop Guided Tour"), NULL);
return 1;
}
hInst = hInstance;
HWND hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, _T("Failed to create a window"), _T("Windows Desktop Guided Tour"), NULL);
return 1;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
HWND button;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello world! This is the first ever application window created by dumb Bhavin.");
switch (message)
{
case WM_CREATE:
button = CreateWindow(_T("BUTTON"),_T("1") ,WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 40, 50, 30, hWnd, (HMENU)1, NULL, NULL);
break;
//////////////////////////////////THIS IS WHERE THE ISSUE IS///////////////////////////////////////////
case WM_COMMAND:
{
if (LOWORD(wParam) == 1)
{
OutputDebugString(_T("The compiler executes this! That means the button is working"));
MessageBox(NULL, L"Here it is", L"ok", NULL); //Message box does not appear at all. The code below it does not execute at all.
OutputDebugString(_T("The compiler DOES NOT execute this!"));
}
break;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
case WM_PAINT:
// hdc = BeginPaint(hWnd, &ps);
// TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
Edit 1:
Here is a small video of what exactly happens.
Error Video
Note : I passed hWnd parameter in this instead of NULL. Passing hWnd as first Parameter does not help either.
The issue was my half-implemented WM_Paint. Uncommenting the BeginPaint line solves the problem.
or, passing it directly to DefWindowProc as return DefWindowProc(hWnd, message, wParam, lParam); works too.

Change window's background color with button using winapi

I'm trying to make button change background color of window when clicked. I know that I need to handle this event in WM_COMMAND, where I also check ID of this button, but nothing happens. I tried to debug and my program recognizes ID correctly. The piece of code used for changing color works well when in main loop but it doesn't do anything when in WM_COMMAND. How do I solve this problem? Whole code:
#include <Windows.h>
#define BUTTON_ID 100
struct status_info {
const char* waiting = "Waiting for connection...";
const char* connected = "Connected.\nWaiting for frajer to copy number.";
const char* changed = "Number changed.";
}status_info;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {
const wchar_t CLASS_NAME[] = L"Name";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = (LPCSTR)CLASS_NAME;
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
RegisterClass(&wc);
//main window
HWND hwnd = CreateWindowEx(0, (LPCSTR)CLASS_NAME, (LPCSTR)"Hacker", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL);
//number window
HWND number = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT("Static"), TEXT("Account number:\n00 1234 1234 1234 1234 1234 1234"), WS_CHILD | WS_VISIBLE, 5, 5, 240, 40, hwnd, NULL, NULL, NULL);
//status window
const char* status_message = status_info.waiting;
HWND status = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT("Static"), TEXT(status_message), WS_CHILD | WS_VISIBLE, 5, 55, 240, 40, hwnd, NULL, NULL, NULL);
//button
HWND button = CreateWindowEx(0, "BUTTON", "Nightmode", WS_CHILD | WS_VISIBLE, 100, 100, 150, 30, hwnd, (HMENU)BUTTON_ID, hInstance, NULL);
MSG msg;
WNDCLASS okno;
while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
SetWindowText(status, status_message);
}
return msg.wParam;
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
//MessageBox(hwnd, L"1", L"1", 0);
return (0);
case WM_DESTROY:
//MessageBox(hwnd, L"2", L"2", 0);
PostQuitMessage(0);
return (0);
case WM_COMMAND: {
if (LOWORD(wParam) == BUTTON_ID) {
PAINTSTRUCT ps;
RECT rc;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
SetBkColor(hdc, BLACK_BRUSH);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, 0, 0, 0);
EndPaint(hwnd, &ps);
}
break;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
BeginPaint/EndPaint should be used in response to WM_PAINT only.
You can use GetDC(hwnd)/ReleaseDC(hwnd, hdc) to obtain hdc for painting on device context outside of WM_PAINT, but this will be temporary. The next refresh message causes the window to be erased and repainted according to what's in WM_PAINT
SetDCBrushColor can be used if the goal is to avoid creating brush handle.
static COLORREF bkcolor = RGB(255,255,255);
switch(message)
{
case WM_COMMAND:
if(LOWORD(wparam) == BUTTON_ID)
{
bkcolor = RGB(255, 0, 0);
InvalidateRect(hwnd, NULL, TRUE);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
SetDCBrushColor(hdc, bkcolor);
FillRect(hdc, &rc, (HBRUSH)GetStockObject(DC_BRUSH));
//or use ps.rcPaint to repaint only the section which requires update
//FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(DC_BRUSH));
EndPaint(hwnd, &ps);
return 0;
}
case WM_ERASEBKGND:
//return 0 means WM_PAINT handles the background
return 0;
Alternatively, use SetClassLongPtr to replace the background brush:
static HBRUSH bkbrush = NULL;
switch(message)
{
case WM_COMMAND:
if(LOWORD(wparam) == BUTTON_ID)
{
COLORREF bkcolor = RGB(rand() % 256, rand() % 256, rand() % 256);
if(bkbrush)
DeleteObject(bkbrush);
bkbrush = CreateSolidBrush(bkcolor);
SetClassLongPtr(hwnd, GCL_HBRBACKGROUND, (LONG)bkbrush);
InvalidateRect(hwnd, NULL, TRUE);
}
break;

Importing a BitMap makes my Window Lagg

I need some help here.
Im importing an bitmap onto my Win32 Window. I am building it and after some seconds it's starting to lag a lot. I am not sure why, but I suppose I am not correctly deleting it from memory after using it.
Thank you for Help in advance.
I saw a behavior while I was testing it. If Im not moving the window than it is okey, but after moving it it start to lag and block my IDE. Maybe something with WM_PAINT?
Here is my code.
#include <windows.h>
//For more makros
#include <windowsx.h>
#include "Simulatron.h"
HINSTANCE hProgramInstance;
Simulatron Exo;
char Simulatron::m_szClassName[] = "Simulatron";
Simulatron::Simulatron(HINSTANCE hInstance)
{
m_hInstance = hInstance; // Save Instance handle
m_wndClass.cbSize = sizeof(WNDCLASSEX); // Must always be sizeof(WNDCLASSEX)
m_wndClass.style = CS_DBLCLKS; // Class styles
m_wndClass.lpfnWndProc = MainWndProc; // Pointer to callback procedure
m_wndClass.cbClsExtra = 0; // Extra bytes to allocate following the wndclassex structure
m_wndClass.cbWndExtra = 0; // Extra bytes to allocate following an instance of the structure
m_wndClass.hInstance = hInstance; // Instance of the application
m_wndClass.hIcon = NULL;//LoadIcon(hInstance, MAKEINTRESOURCE(IDC_MAINCURSOR)); // Class Icon
m_wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Class cursor
m_wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Background brush
m_wndClass.lpszMenuName = NULL; // Menu Resource
m_wndClass.lpszClassName = (LPCWSTR)m_szClassName; // Name of this class
m_wndClass.hIconSm = NULL;//LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); // Small icon for this class
}
Simulatron::~Simulatron()
{
}
Simulatron::Simulatron()
{
// If we declare a window class with a default constructor,
// we need to reset the window to a nothing
}
LRESULT CALLBACK Simulatron::MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HDC hdc;
static PAINTSTRUCT ps;
static HDC hdc_mem;
static HBRUSH newbrush;
//Child Window Handles
Simulatron create;
RECT rect;
hProgramInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
static HBITMAP logo = NULL;
static BITMAP bitmap;
logo = (HBITMAP)LoadImage(hProgramInstance, L"Space.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(logo, sizeof(bitmap), &bitmap);
switch (msg)
{
case WM_CREATE:
{
create.Create(hProgramInstance,hwnd,lParam,logo);
}
break;
case WM_GETMINMAXINFO:
{
LPMINMAXINFO pInfo = (LPMINMAXINFO) lParam;
//pInfo -> ptMaxTrackSize.x = 450;
//pInfo -> ptMaxTrackSize.y = 650;
}
break;
case WM_SIZE:
break;
case WM_CTLCOLORSTATIC:
SetTextColor((HDC)wParam, RGB(150, 100, 255));
SetBkMode((HDC)wParam, TRANSPARENT);
newbrush = (HBRUSH)GetStockObject(NULL_BRUSH);
DeleteObject(newbrush);
return (LRESULT)newbrush;
break;
case WM_COMMAND:
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd , &rect);
hdc_mem = CreateCompatibleDC(hdc);
SelectObject(hdc_mem, logo);
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdc_mem, 0, 0, SRCCOPY);
DeleteObject(hdc_mem);
EndPaint(hwnd, &ps);
break;
//Handle the combinations from the keyboard input
case WM_DESTROY:
PostQuitMessage (0);
DeleteObject(logo);
DeleteBitmap(logo);
break;
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
return 0;
}
//Create function of all Childs
void Simulatron::Create(HINSTANCE Hinst, HWND hWindow, LPARAM lParam, HBITMAP logo)
{
Hinst = ((LPCREATESTRUCT) lParam) -> hInstance; // handle to instance for custom cursor
logo = (HBITMAP)LoadImage(Hinst, L"Space.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
bool Simulatron::Run(int nCmdShow)
{
if(!RegisterClassEx(&m_wndClass))
return false;
m_hwnd = CreateWindowEx(0,(LPCWSTR)m_szClassName,
L"Simulatron",
//WS_OVERLAPPEDWINDOW,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // Dissable Resizing and Maximizing
0, 0, 1280, 1000,
NULL, NULL,
m_hInstance,
NULL);
if(!m_hwnd)
return false;
ShowWindow(m_hwnd, nCmdShow);
return true;
}
Simulatron::operator HWND()
{
// This overloaded operator allows us to use HWND anyway we want
return m_hwnd;
}
You load the BMP File over and over again in your MainWndProc. You should load it once at Init and use it from there! Have a look at a win32 API tutorial and you will see that MainWndProc is getting called throughout the whole program lifetime. You could load that image in your WM_CREATE state for example.