Create custom window resize functionality - c++

I'm trying to create a borderless, captionless, and resizeable without using the WS_THICKFRAME, WS_BORDER and WS_SIZEBOX styles.
I don't want to use these styles because they create a border but more importantly, when I use the SetWindowCompositionAttribute function to enable an acrylic blur behind on the window, the blur goes past the window for some reason .
I checked out this repo and I'm currently using their hit testing logic.
So essentially I believe I need to implement my own resizing ability but I don't know where to really start.

There is a lot of nuance to exactly replicating all standard window resizing behavior but the main thing you need to do is implement your own handler of WM_NCHITTEST, which basically tells Windows which part of the window a given point is in.
Here's an example that will allow dragging via a custom title bar area and resizing via dragging the left, right, and bottom of the window.
#include <windows.h>
#include <tuple>
#include "windowsx.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"customwindowresizing";
if (!RegisterClass(&wc))
return 1;
if (!CreateWindow(wc.lpszClassName,
L"",
WS_POPUP | WS_VISIBLE,
0, 0, 640, 480, 0, 0, hInstance, NULL))
return 2;
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
return 0;
}
LRESULT HandleNonclientHitTest(HWND wnd, LPARAM lparam, int title_bar_hgt, int resizing_border_wd)
{
RECT wnd_rect;
GetWindowRect(wnd, &wnd_rect);
int wd = wnd_rect.right - wnd_rect.left;
int hgt = wnd_rect.bottom - wnd_rect.top;
RECT title_bar = { 0,0, wd, title_bar_hgt };
RECT left = { 0, title_bar_hgt , resizing_border_wd , hgt - title_bar_hgt - resizing_border_wd };
RECT right = {wd - resizing_border_wd , title_bar_hgt , wd, hgt - title_bar_hgt - resizing_border_wd };
RECT bottom = { 0, hgt - resizing_border_wd, wd, hgt };
std::tuple<RECT, LRESULT> rects[] = {
{title_bar, HTCAPTION},
{left, HTLEFT},
{right, HTRIGHT},
{bottom, HTBOTTOM}
};
POINT pt = { GET_X_LPARAM(lparam) - wnd_rect.left, GET_Y_LPARAM(lparam) - wnd_rect.top };
for (const auto& [r, code] : rects) {
if (PtInRect(&r, pt))
return code;
}
return HTCLIENT;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_NCHITTEST:
return HandleNonclientHitTest(hWnd, lParam, 25, 10);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

So essentially I believe I need to implement my own resizing ability
Actually, you don't. If you only want to resize via the bottom-right hand corner of the window, just catch WM_NCHITTEST and return HTGROWBOX when the mouse is in the area of the window that you consider to be your resizing handle.
Other, more complex, return values from WM_NCHITTEST are possible (including making it possible for the user to drag the window around on the screen), but you get the idea.

Related

snap layouts menu doesn't appear on windows 11 for custom maximize button

My goal is to create a custom maximize button for my app and I also want to trigger snap layouts menu on the button on Windows 11. For that, I am following the guide from here, but it doesn't work.
Here is the sample code, For testing purpose, I take a rectangle {point(0,0), size(200,200)} and when the mouse is over it and I receive WM_NCHITTEST message I return the HTMAXBUTTON as instructed in the guide but the snap layouts menu doesn't show up.
#include <stdio.h>
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <windowsx.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Test Window", // 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) > 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;
case WM_NCHITTEST:
{
// Get the point in screen coordinates.
// GET_X_LPARAM and GET_Y_LPARAM are defined in windowsx.h
POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
// Map the point to client coordinates.
::MapWindowPoints(nullptr, hwnd, &point, 1);
RECT maximizeRect {0, 0, 200, 200};
// If the point is in your maximize button then return HTMAXBUTTON
if (::PtInRect(&maximizeRect, point))
{
printf("maxmize button rect %d\n", rand());
fflush(stdout);
return HTMAXBUTTON;
}
break;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
At the beginning, custom title bar before supporting the snap layouts menu
maximizeRect is client coordinates and not the maximize button rectangle.
The WM_NCHITTEST return value is wrong. If the point is in your maximize button then return HTMAXBUTTON.
There is a HitTestNCA example which calculates in the screen coordinate instead of the client coordinate and works fine. Another win32-window-custom-titlebar sample.

The Bottom Border of a simple Windows Application keeps disappearing and reaapearing when resizing the window

Here's a simple Win32 Application that I copied from the official MSDN docs (link):
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&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);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_DESKTOP+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
The only difference is I used COLOR_DESKTOP instead of COLOR_WINDOW in FillRect() (this problem occurs in both the cases).
Whenever I resize the window, the bottom border keeps disappearing and then reappearing as I resize it further. Can anyone tell what's happening?
Here's GIF to show the bottom border disappearing when resizing:
I suggest you could try to enable DPI awareness: Property -> Manifest Tool ->Input and Output -> DPI Awareness.

How can I add some text line in my window?

I am able to create a window with a Tile. How can I add now new text line inside the Window ?
All what I succeed to did was only to change the title of the window which is not what I want . I want to add some text line in the window box.
SendMessage function was not working for me.
Please if somebody has some tip for this to tell me !
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
//The Window Procedure
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;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Title of window",
WS_OVERLAPPEDWINDOW,
1390, 540, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
To draw text in the client area, your wndProc would normally use something like DrawText or TextOut. You typically do that in response to WM_PAINT.
To be able to respond to an external message, you'd typically send a message containing the text. The window would receive that, store (a copy of) the text it received, and (usually) invalidate the window's rectangle. Since the window is now invalidated, the next chance it gets, Windows will send your window a WM_PAINT message (and then you'll draw out the text).
Handling the WM_PAINT message and drawing the text directly on the window's HDC is one option.
Another option is to create a child STATIC control in your window, and then you can assign the desired text to that child using SetWindowText() or the WM_SETTEXT message. No manual drawing needed.
In the end I figure out how to finish this:
win32 app picture
#ifndef UNICODE
#define UNICODE
#endif
using namespace std;
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
int X_Coordinate = 215;
int Y_Coordinate = 415;
int Width = 700;
int Height = 500;
char Text[] = {"abc123"};
char Window_Title[] = "My title";
char Window_Image[] = "D:\\bitmap1.bmp";
const char* csWindow_Title = Window_Title;
const char* csWindow_Image = Window_Image;
HBITMAP bitmap; // Creates bitmap object based on a handle to a Windows Windows Graphics Device Interface (GDI) bitmap and a handle to a GDI palette.
// Utilities
bool ConvertConstChartoLPWSTR (const char* as , wchar_t* wString )
{
memset(wString,0,sizeof(wString));
MultiByteToWideChar(CP_ACP, 0, as, -1, wString, 4096);
return wString;
}
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";
WNDCLASS wc = { };
//Registering the Window Class
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hbrBackground = CreateSolidBrush(RGB(255, 255, 255)); // set window background color ( RGB ) - white
RegisterClass(&wc); // register the window class with the operating system
wchar_t* wWindow_Title=new wchar_t[4096];
memset(wWindow_Title,0,sizeof(wWindow_Title)); // init variable
ConvertConstChartoLPWSTR(csWindow_Title,wWindow_Title); // convert
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
wWindow_Title, // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
X_Coordinate, Y_Coordinate, Width, Height,
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;
}
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// ----------------------------- START -> SWITCH case -----------------------------------------------------
switch (uMsg)
{
// ----------------------------- START -> case WM_DESTROY -------------------------------------------------
case WM_DESTROY:
PostQuitMessage(0);
return 0;
// ----------------------------- END -> case WM_DESTROY ---------------------------------------------------
// ----------------------------- START -> case WM_PAINT ---------------------------------------------------
case WM_PAINT:
{
wchar_t* wWindow_Image=new wchar_t[4096];
memset(wWindow_Image,0,sizeof(wWindow_Image));
ConvertConstChartoLPWSTR(csWindow_Image,wWindow_Image); // convert
bitmap=(HBITMAP)LoadImage(NULL, // A handle to the module that contains the image to be loaded. To load a stand-alone resource (icon, cursor, or bitmap file)—for example, c:\myimage.bmp — set this parameter to NULL
wWindow_Image, // The image to be loaded.
IMAGE_BITMAP, // The type of image to be loaded.
690, // The width, in pixels, of the icon or cursor.
540, // he height, in pixels, of the icon or cursor.
LR_LOADFROMFILE); //Loads the stand-alone image from the file specified by lpszName (icon, cursor, or bitmap file).
PAINTSTRUCT ps; // declare structure with information for an application
HDC hdc = BeginPaint(hwnd, &ps); // prepare the specified window for painting
int index = sizeof(Text);
HDC hMemDC=CreateCompatibleDC(hdc); // create a compatible DC ( hMemDC ) o be the same like another one ( hdc )
::SelectObject(hMemDC,bitmap); // Selects an object into the specified device context (DC). The new object replaces the previous object of the same type.
long retval=SetTextAlign(hdc,TA_TOP); // alignment of written area
const char* theval;
int u = 5;
for(int b = 0; b < sizeof(Text); b++)
{
string sym(1, Text[b]); // convert char to const char*
theval = sym.c_str();
cout<<b<<theval;
wchar_t wtext[sizeof(Text)];
memset(wtext,0,sizeof(wtext));
ConvertConstChartoLPWSTR(theval,wtext); // convert
// Here application is laid out.
TextOut (hdc, 5, u, wtext, sizeof(Text));
u = u + 15;
}
index = index + u; // claculate the size of written area
BitBlt( hdc, // handler
0, // The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
index, // The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
700, // The width, in logical units, of the source and destination rectangles.
980, // The height, in logical units, of the source and the destination rectangles.
hMemDC, // handler for source ( image ).
0, // The x-coordinate, in logical units, of the upper-left corner of the source rectangle.
0, // The y-coordinate, in logical units, of the upper-left corner of the source rectangle.
SRCCOPY ); // A raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color.
// SRCCOPY - Copies the source rectangle directly to the destination rectangle.
EndPaint(hwnd, &ps); // function marks the end of painting in the specified window
}
return 0;
// ----------------------------- END -> case WM_PAINT ---------------------------------------------------
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
// ----------------------------- END -> SWITCH case -----------------------------------------------------
} // END -> LRESULT CALLBACK WindowProc

Creating custom windows border edge disapears when resize smaller

Pretty much what the title says.
Im trying to make my own border, like that of visual studio 2015.
Once i have the border working like it should i will add a child window that is the main window for my program, the border will be the parent.
Will also try and add a outer glow once i get it working.
But the problem im having right now is, When i drag my border to resize it to make it smaller, The right or bottom start to get thinner depending on how fast i drag the mouse.
Is there a better way to do this or is there a simple step i can take to fix it.
#include <windows.h>
LPTSTR className_ = TEXT("BorderWindow");
BOOL WINAPI Init(HINSTANCE hInstance, INT cmdShow);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow) {
MSG msg;
if (!Init(hInstance, nCmdShow)) {
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (INT)msg.wParam;
}
BOOL WINAPI Init(HINSTANCE hInstance, INT cmdShow)
{
WNDCLASSEX wcex{ 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT + 1);
wcex.lpszClassName = className_;
wcex.hIconSm = NULL;
if (!RegisterClassEx(&wcex)) {
return FALSE;
}
HWND hwnd_ = CreateWindow(className_, className_, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 200, 500, nullptr, nullptr, hInstance, nullptr);
if (!hwnd_)
return FALSE;
ShowWindow(hwnd_, cmdShow);
UpdateWindow(hwnd_);
return TRUE;
}
void CreateHole(HWND hWnd)
{
HRGN WindowRgn;
HRGN HoleRgn;
//Get the window region:
RECT windowrect;
GetWindowRect(hWnd, &windowrect);
int width = windowrect.right - windowrect.left;
int height = windowrect.bottom - windowrect.top;
WindowRgn = CreateRectRgn(0, 0, width, height);
//Create the hole region:
HoleRgn = CreateRectRgn(2, 2, width - 2, height - 2);
CombineRgn(WindowRgn, WindowRgn, HoleRgn, RGN_DIFF);
SetWindowRgn(hWnd, WindowRgn, TRUE);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
CreateHole(hwnd);
return 0;
case WM_NCCALCSIZE:
// remove default borders
return 0;
case WM_NCHITTEST:
{
RECT rc;
GetClientRect(hwnd, &rc);
POINT pt = { LOWORD(lparam), HIWORD(lparam) };
ScreenToClient(hwnd, &pt);
if (pt.y > (rc.bottom - 5))
{
if (pt.x > (rc.right - 5))
{
return HTBOTTOMRIGHT;
}
}
return HTBORDER;
}
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
If you only need rectangular frame, an easier solution can be achieved as follows:
Window style should be such that normally the whole frame would be shown (WS_CAPTION|WS_POPUP works well for me).
Call DwmExtendFrameIntoClientArea() with MARGINS{0,0,0,1}.
Call SetWindowPos(nullptr, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED) to recalculate NC area.
Return 0 from WM_NCCALCSIZE if wParam is TRUE. This has the effect of extending the client area to the window size including frame. The regular window frame will be removed, but shadow will still be drawn by DWM (see also remarks section of WM_NCCALCSIZE).
In WM_PAINT draw your frame and content area as you like but make sure to set opaque alpha channel for the margin defined by the DwmExtendFrameIntoClientArea() call. Otherwise part of regular frame would be visible in this area. You may use GDI+ for that as most regular GDI functions ignore alpha channel.
You can put child controls into this window, just as normal. Just make sure child controls don't overlap the margin defined by the DwmExtendFrameIntoClientArea() call because most GDI controls ignore the alpha channel.

C++ Win32 Background Image

I have looked at some background drawing tutorials but I still can't draw my background; it's always white. My resources are already in the project. I have tried a few other ways by using paint instead but it still would not draw the background image.
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND hProgress, hWndBottom;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
hInst = hInstance;
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = CreatePatternBrush( LoadBitmap( hInstance, MAKEINTRESOURCE(IDB_BG) ));//(HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = "Test";
if( !RegisterClass(&wc) )
return 1;
if( !CreateWindow(wc.lpszClassName,
"Tests",
WS_POPUPWINDOW|WS_VISIBLE, //WS_OVERLAPPEDWINDOW|WS_VISIBLE
1,1,200,250,0,0,hInstance,NULL))
return 2;
while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
DispatchMessage( &msg );
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//Make TopMost
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
switch(message)
{
case WM_CREATE:
{
hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL,
WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
10, 190, 170, 10,
hWnd, NULL, hInst, NULL);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
If you're going to draw a bitmap for your background, you do not just set the background brush to the handle of your bitmap.
Instead, you set the background brush to NULL, and handle the WM_ERASEBKGND message. You respond to it by drawing your bitmap (e.g., with BitBlt or StretchBlt), then you return TRUE (or any other non-zero value) to tell DefWindowProc that the background has been erased, so it shouldn't try to erase it.
Note that if you're doing this in an MDI program, you need to do this in the MDI client window. With MDI, you have a parent window, a client window, and some number of MDI child windows. What looks like the background of the main window is really occupied by the MDI client window, so that's where you need to draw in your background.