create transparent image from png, winapi - c++

I created a simple form to test in winapi: I uploaded here: http://pastebin.com/7dNjE1Tb
I would like to put a simple png file to my hwnd, for example this picture: http://www.ledavi-network.com/includes/images/bg_shadow_png.png
I know I should use this: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145141(v=vs.85).aspx but I am very new in winapi and I dont find any example how to use this TransparentBlt function.
Someone could help me to create a very simple example?
EDIT:
But what I would like to do?
I would like to create a button which has special background with shadow. So If anyone know an easier way to do this, I will forget to use the TransparentBlt. So any else solution?

Here, this will do the job. You'll need to ensure you have gdiplus and msimg32 libraries linked for the AlphaBlend (TransparentBlt assumes that a single rgb color in the image will be treated as transparent. I.e it's just 1-bit transparency when using TransparentBlt - fully opaque or fully transparent.)
You'll (presumably) wish to use AlphaBlend for this job.
Note - I haven't bothered to add an WM_ERASEBKGND to the WndProc function. As a consequence, each time the image is re-drawn, it's drawn straight over the top of what's already there (try resizing the window). Just do a FillRect in erasebkg, and you'll be fine.
EDIT: Code updated to use displayImage with a NULL hbitmap to do the background too.
Here 'go:
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0600 // needed for alphablend function..
#include <windows.h>
#include <gdiplus.h>
const char g_szClassName[] = "myWindowClass";
// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
// requires GDIPlus
HBITMAP mLoadImg(WCHAR *szFilename)
{
HBITMAP result=NULL;
Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(szFilename,false);
bitmap->GetHBITMAP(NULL, &result);
delete bitmap;
return result;
}
//void CStaticImg::displayImage(HBITMAP mBmp, HWND mHwnd)
void displayImage(HBITMAP mBmp, HWND mHwnd)
{
RECT myRect;
BITMAP bm;
HDC screenDC, memDC;
HBITMAP oldBmp;
BLENDFUNCTION bf;
GetObject(mBmp, sizeof(bm), &bm);
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xff;
bf.AlphaFormat = AC_SRC_ALPHA;
screenDC = GetDC(mHwnd);
GetClientRect(mHwnd, &myRect);
if (mBmp == NULL)
FillRect(screenDC, &myRect, WHITE_BRUSH);
else
{
memDC = CreateCompatibleDC(screenDC);
oldBmp = (HBITMAP)SelectObject(memDC, mBmp);
AlphaBlend (screenDC, 0, 0, myRect.right,myRect.bottom, memDC, 0, 0, bm.bmWidth,bm.bmHeight, bf);
SelectObject(memDC, oldBmp);
DeleteDC(memDC);
ReleaseDC(mHwnd, screenDC);
}
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HBITMAP myImage;
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_ERASEBKGND:
displayImage(NULL, hwnd);
break;
case WM_CREATE:
myImage = mLoadImg(L"bg_shadow_png.png");
break;
case WM_PAINT:
//displayImage(HBITMAP mBmp, HWND mHwnd);
displayImage(myImage, hwnd);
ValidateRect(hwnd, NULL);
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;
static Gdiplus::GdiplusStartupInput gdiplusStartupInput;
static ULONG_PTR gdiplusToken;
// so we can load all the image formats that windows supports natively - (I'm using a transparent PNG on the main dialog)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
//Step 1: 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;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 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);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
Gdiplus::GdiplusShutdown(gdiplusToken);
return Msg.wParam;
}

Related

How to set a BMP image as the background of a window in Windows API C++?

LATER EDIT:
I realised that what was wrong was not my code, but the image itself. Do not use online tools for converting from jpg to bmp, as they don't provide usable images. What I did instead was open the jpg in Paint and then save it as a 24-bit Bitmap (the only one which kept my original colours).
ORIGINAL POST:
I am trying to make a pretty home window as part of a game, but I don't understand many things in WIN 32.
I want to create a window which will also have some buttons and I also want to set its background to a .bmp image, not a solid colour. How can I set an image as a background (in C++)?
The image I am talking about is saved as "bg1.bmp", both in the first folder of my project (along with the source code and the .cbp file) and in the bin/Debug/ folder, where the .exe is. The window whose background I am trying to set has the handle hwnd.
I have tried defining the background when defining the window class, but this brings no change at all to the window:
wincl.hbrBackground=CreatePatternBrush((HBITMAP) LoadImage(0,_T("bg1.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE));
and also having another static window of the same size overlapping the main window, which gives me a black window instead of a white one.
background=CreateWindow("STATIC","background",SS_BITMAP|WS_CHILD | WS_VISIBLE,0,0,300,300,hwnd,NULL,NULL,NULL);
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "seamless_background1.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
SendMessage(background, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
but this one just gives me a black window.
Could you tell me what's wrong with the code? Also, is there any neater way of doing this?
I used the same code and created the simplest Windows Desktop Application.
And I use my own bmp image to test the background and static window image successfully.
I think the problem lies in your image format, if you just changed the suffix of an other image to .bmp, then your LoadImage will fail but GetLasterror will return 0.
I suggest you try to test with other bmp images in the correct format so that you can get the correct results.
This is my sample:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("test windows");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = CreatePatternBrush((HBITMAP)LoadImage(NULL, L"D:\\VS_test_projects\\win_api\\bitmap.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE));;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
}
hwnd = CreateWindow(szAppName,
TEXT(""test windows""),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
HWND background = CreateWindow(L"STATIC", L"background", SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 300, 300, hwnd, NULL, NULL, NULL);
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, L"test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
int e = GetLastError();
SendMessage(background, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
And it works like this(Ignore the pictures I use that are not pretty):

Fit string inside specified rectangle

I have string that needs to be drawn inside rectangle.
The problem lies in the fact that sometimes string can be too big to fit inside.
How can I adjust font size so the string can fit inside?
I have read the docs for GDI and found nothing. I still keep searching on the Internet, hoping to find something or to get an idea of my own...
GDI+ is an option too...
The following code is posted in response to comment from user Jonathan Potter:
#include <windows.h>
#include <windowsx.h>
#include <CommCtrl.h>
#include <stdio.h> // swprintf_s()
#include <math.h>
#include <gdiplus.h>
#include <string>
using namespace Gdiplus;
// enable Visual Styles
#pragma comment( linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
language='*'\"")
// link with Common Controls library
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "GdiPlus.lib")
//global variables
HINSTANCE hInst;
// main window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
RECT rcClient = { 0 };
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rcClient);
int pageWidth = rcClient.right - rcClient.left,
pageHeight = rcClient.bottom - rcClient.top;
HFONT font = NULL, oldFont = NULL;
// target rectangle, text should fit inside
Rectangle(hdc, 0, 0, pageWidth / 4, pageHeight / 10);
SIZE sz;
GetTextExtentPoint32(hdc, L"This is very long string that might not fit into specified rectangle",
lstrlen(L"This is very long string that might not fit into specified rectangle"), &sz);
if (sz.cx > (pageWidth / 4))
{
// get current font
LOGFONT lf;
GetObject(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
// scale it
lf.lfHeight = MulDiv(lf.lfHeight, (pageWidth / 4), sz.cx);
font = CreateFontIndirect(&lf);
oldFont = SelectFont(hdc, font);
}
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255, 0, 0));
// draw text in test rectangle
RECT rcText = { 0 };
rcText.left = 0;
rcText.top = 0;
rcText.right = pageWidth / 4;
rcText.bottom = pageHeight / 10;
DrawTextEx(hdc,
L"This is very long string that might not fit into specified rectangle",
wcslen(L"This is very long string that might not fit into specified rectangle"),
&rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOCLIP, NULL);
if (font != NULL)
{
SelectFont(hdc, oldFont);
DeleteFont(font);
}
EndPaint(hwnd, &ps);
}
return 0L;
case WM_SIZE:
{
InvalidateRect(hwnd, NULL, TRUE);
}
return 0L;
case WM_CLOSE:
::DestroyWindow(hwnd);
return 0L;
case WM_DESTROY:
{
::PostQuitMessage(0);
}
return 0L;
default:
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
// store hInstance in global variable for later use
hInst = hInstance;
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// register main window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Main_Window";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// initialize common controls
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_LISTVIEW_CLASSES | ICC_STANDARD_CLASSES;
InitCommonControlsEx(&iccex);
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// create main window
hwnd = CreateWindowEx(0, L"Main_Window", L"Autofit text inside rectangle",
WS_OVERLAPPEDWINDOW, 50, 50, 200, 200, NULL, NULL, hInstance, 0);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
GdiplusShutdown(gdiplusToken);
return Msg.wParam;
}
You're looking for DrawText:
int DrawText(_In_ HDC hDC,
_Inout_ LPCTSTR lpchText,
_In_ int nCount,
_Inout_ LPRECT lpRect,
_In_ UINT uFormat
);
You specify the rectangle, and it ensures the text does not get drawn outside of that rectangle. It also has a DT_CALCRECT flag if you need to calculate the rectangle based on the text and the current selected font. Or you can use the DT_END_ELLIPSIS, DT_PATH_ELLIPSIS or DT_WORD_ELLIPSIS flag to truncate the drawing of the text with ellipsis added so the user can see when the text is longer than the rectangle.
In theory, something like this should work, but I haven't tested it. Add appropriate error checking etc.
SIZE sz;
GetTextExtentPoint32(hDC, pszMyString, lstrlen(pszMyString), &sz);
if (sz.cx > iMyMaximumWidth)
{
// get current font
LOGFONT lf;
GetObject(GetCurrentObject(hDC, OBJ_FONT), sizeof(lf), &lf);
// scale it
lf.lfHeight = MulDiv(lf.lfHeight, iMyMaximumWidth, sz.cx);
HFONT hNewFont = CreateFontIndirect(&lf);
.. use hNewFont to render string, remember to delete it when done
}

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.

My LoadImage isn't Working - I need to know why

Look At this code and please tell me why when I compile it I see a blank white screen:
#include <windows.h>
#include <fstream.h>
#include <stdlib.h>
static char g_szClassName[] = "TEST";
static HINSTANCE g_hInst = NULL;
int savenumber = 1;
char savestring[] = "abc";
HWND hwnd;
HDC hdcWindow;
PAINTSTRUCT ps;
RECT rc;
//HBITMAP mario1,mario2,mario3,mario4,mario5,mario6,
// block1,block2,block3,scene1,scene1mask;
HBITMAP scene1;
BITMAP bm;
LRESULT CALLBACK
WndProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
HBITMAP g_hbitmap = NULL;
switch(nMsg)
{
case WM_CREATE:
g_hbitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL),
"C:\\Users\\Onwer\\Desktop\\Cpp code Initiate\\Jacob GRAPIC#3 cpp renewal!\\G3-Images\\scene.bmp",
IMAGE_BITMAP,
640,
320,
LR_LOADFROMFILE);
/*
mario1 = LoadBitmap(g_hInst, "MARIO1BMP");
mario2 = LoadBitmap(g_hInst, "MARIO2BMP");
mario3 = LoadBitmap(g_hInst, "MARIO3BMP");
mario4 = LoadBitmap(g_hInst, "MARIO4BMP");
mario5 = LoadBitmap(g_hInst, "MARIO5BMP");
mario6 = LoadBitmap(g_hInst, "MARIO6BMP");
block1 = LoadBitmap(g_hInst, "BLOCK1BMP");
block2 = LoadBitmap(g_hInst, "BLCOK2BMP");
block3 = LoadBitmap(g_hInst, "BLOCK3BMP");
scene1 = LoadBitmap(g_hInst, "SCENE1BMP");
scene1mask = LoadBitmap(g_hInst, "SCENE1MASKBMP");
*/
scene1 = LoadBitmap(g_hInst, "SCENE1BMP");
break;
case WM_TIMER:
break;
case WM_PAINT:
hdcWindow = BeginPaint(hwnd, &ps);
GetClientRect (hwnd, &rc);
drawScene (hdcWindow);
//DrawText(hdcWindow,"This Is a Test!", -1, &rc,
//DT_SINGLELINE | DT_TOP | DT_TOP );
EndPaint(hwnd, &ps);
break;
case WM_COMMAND:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
/*
DeleteObject(mario1);
DeleteObject(mario2);
DeleteObject(mario3);
DeleteObject(mario4);
DeleteObject(mario5);
DeleteObject(mario6);
DeleteObject(block1);
DeleteObject(block2);
DeleteObject(block3);
*/
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, nMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
ofstream SaveFile ("save.txt");
SaveFile << savenumber << '\n' << savestring;
WNDCLASSEX WndClass;
HWND hwndMain;
MSG Msg;
g_hInst = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = g_szClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass))
{
MessageBox(0, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"TEST",
WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, CW_USEDEFAULT, 677, 358,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 500,
NULL, NULL, g_hInst, NULL);
if(hwnd == NULL)
{
MessageBox(0, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
I need to know why LoadImage doesn't display the picture designated. Is it not even supposed to? And if its not supposed t: tell me what function that goes with loadImage I should use, that is part of Windows.h in C++. I am using the Dev-C++ compiler.
All LoadImage does it loads an image, nothing else. If you want your application to draw an image in a window you have to do it yourself.
The contents of drawScene() were commented out (since removed in an edit) and your WM_PAINT handler doesn't perform any drawing operations. If your bitmap was successfully loaded you will need to do something like below when you handle the WM_PAINT message.
hdcMemory = CreateCompatibleDC(hdcWindow);
HGDIOBJ oldBitmap = SelectObject(hdcMemory, g_hbitmap);
BitBlt(hdcWindow, 0, 0, 640, 320, hdcMemory, 0, 0, SRCCOPY);
SelectObject(hdcMemory, oldBitmap);
DeleteDC(hdcMemory);

How to duplicate a window's clientarea to another window?

I want to create a simple project (the language doesn't really matter/but I prefer C++) which simply takes a window title as it's input and duplicate it's visual part, bit by bit, to a new window. just like a mirror better I'd say.
As far as I remember there was a win32 API for this but I can't remember, so would you please tell me how can I achieve this?
And please tell me, will your answers work with DirectX/Open-GL applications as well or not?
You can get DC of first window, and get DC of second window. And after this do BitBlt or StretchBlt. It has to work... But I don't know what about DirectX/Open-Gl... I think it has to work too. But anyway. It won't take much time to check it.
Here is the source code for a program that will mirror other apps, you can use StretchBlt() instead of BitBlt(), this will not copy Menubars or popups.
Some apps like chrome, calculator, and camera use child windows for the visual part, and FindWindow() only scans through top-level windows for the title, so you can use FindWindowEx() with it to make that work!
#include <windows.h>
HWND sourceWindow;
void Mirror(HWND hwndSource, HWND hwndDst)
{
HDC source = GetDC(hwndSource);
HDC dst = GetDC(hwndDst);
RECT srcSiz;
GetClientRect(hwndSource, &srcSiz);
SetWindowPos(hwndDst, NULL, 0, 0, srcSiz.right, srcSiz.bottom, SWP_NOMOVE | SWP_NOZORDER);
BitBlt(dst, 0, 0, srcSiz.right, srcSiz.bottom, source, 0, 0, SRCCOPY);
ReleaseDC(hwndSource, source);
ReleaseDC(hwndDst, dst);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_CREATE:
SetTimer(hwnd, 1, 500, (TIMERPROC) NULL);//This will refresh after every 500 ms
break;
case WM_TIMER:
Mirror(sourceWindow, hwnd);
break;
case WM_DESTROY:
KillTimer(hwnd, 1);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(0, 0, 0)));
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyWindow";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindow", "MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
sourceWindow = FindWindowA(NULL, "<WindowTitle>");//or you can use class name
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}