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);
Related
When I add a menubar to a window, the window didn't resize accordingly because the top portion is hidden by the menubar. I want to resize the window while taking account of menubar's height. This is what I tried.
/* g++ test.cpp -o test -Wl,-subsystem,windows */
#include <Windows.h>
#define ID_OPEN 0
#define ID_EXIT 1
#define ID_ABOUT 2
const int width = 500;
const int height = 400;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szWndClassName[] = TEXT("hellowin");
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
//Step 1: Registering the Window Class
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 = (HBRUSH) COLOR_BACKGROUND;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szWndClassName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program only works in Windows NT or greater!"), TEXT("Hey dude!"), MB_OK | MB_ICONERROR);
return 1;
}
// Step 2: Creating the Window
hWnd = CreateWindow(szWndClassName, /* window class name */
TEXT("Hey!"), /* window title (or caption) */
WS_OVERLAPPEDWINDOW, /* window style */
CW_USEDEFAULT, /* initial x position */
CW_USEDEFAULT, /* initial y position */
width, /* initial window width */
height, /* initial window height */
NULL, /* parent window handle */
NULL, /* window menu handle */
hInstance, /* program instance handle */
NULL); /* creation parameters */
if (hWnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
// Step 3: The Message Loop (heart)
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
// Step 4: the Window Procedure (brain)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HMENU hMenuBar = CreateMenu();
HMENU hFile = CreatePopupMenu();
HMENU hHelp = CreatePopupMenu();
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hFile, "File");
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hHelp, "Help");
AppendMenu(hFile, MF_STRING, ID_OPEN, "Open");
AppendMenu(hFile, MF_STRING, ID_EXIT, "Exit");
AppendMenu(hHelp, MF_STRING, ID_ABOUT, "About");
SetMenu(hWnd, hMenuBar);
PMENUBARINFO pmbi;
GetMenuBarInfo(hWnd, OBJID_MENU, 0, pmbi);
RECT menuRect;
RECT windRect;
GetWindowRect(pmbi->hwndMenu, &menuRect);
GetWindowRect(hWnd, &windRect);
int width = menuRect.right - menuRect.left;
int height = (menuRect.bottom - menuRect.top) + (windRect.bottom - windRect.top);
SetWindowPos(hWnd,
0,
0,
0,
width,
height,
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("Hello World!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
I tried to retrieve rectangles of both menubar and the window and calculate the new dimension like this
int width = menuRect.right - menuRect.left;
int height = (menuRect.bottom - menuRect.top) + (windRect.bottom - windRect.top);
Unfortunately the code crashes. I have no idea which part I did wrong. Any ideas?
pmbi is an uninitialised pointer variable. Passing it to GetMenuBarInfo is therefore the likely cause of your crash. If that doesn't crash, then attempting to access pmbi->hwndMenu probably will.
Instead, you want:
MENUBARINFO mbi;
mbi.cbSize = sizeof (mbi); // see documentation
GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi);
...
which tells GetMenuBarInfo to fill in the (stack-based) variable mbi.
Then replace pmbi->hwndMenu with mbi.hwndMenu and that should fix your problem.
I am trying to write code where the user is able to choose an image from their computer. I was able to get a piece of code working where the window would update itself when the user choosed an image. So, I went ahead and added some buttons to the screen and now, the image wont even load onto the screen. I'm confused as to why. It's not the image size because I chose a small image to load in as well.
Here is my function for putting the image up:
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(filePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
}
And here's my paint:
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
EndPaint(hWnd, &ps); } break;
I just added the buttons with CreateWindowW with WS_VISIBLE and WS_CHILD.
If you set the absolute path of the file, your code will work. It is worth mentioning that you can comment RedrawWindow, because this function will repeatedly refresh the window and cause flicker.
This is a reproducible example, you can try:
#include <Windows.h>
#include <ObjIdl.h>
#include <gdiplus.h>
#include <uxtheme.h>
#include <shobjidl_core.h>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment(lib,"Uxtheme")
#define MAX_LOADSTRING 100
#define IDB_BUTTON1 101
using namespace Gdiplus;
using namespace std;
void putImage(HDC, HWND);
void Opendialog();
HWND hwnd;
PWSTR pszFilePath;
BOOL flag = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
{
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
500, // x position
10, // y position
100, // Button width
100, // Button height
hwnd, // Parent window
(HMENU)IDB_BUTTON1, // No menu.
(HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDB_BUTTON1:
Opendialog();
flag = 1;
InvalidateRect(hwnd, NULL, FALSE);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
HRESULT hr = S_OK;
PAINTSTRUCT ps;
HDC screen = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code that uses hdc here...
if (flag == 1)
{
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hwnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hwnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
flag = 0;
}
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
//Initialize GDI+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = L"win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow(L"win32", L"My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(pszFilePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
// RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
}
void Opendialog()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog* pFileOpen;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
// Show the Open dialog box.
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr))
{
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr))
{
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr))
{
// MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
}
Debug:
Updated:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>
#include <string>
#include<string.h>
#include <iostream>
#include <uxtheme.h>
#include <shobjidl.h>
#include <objidl.h>
#include <gdiplus.h>
#include <gdiplusheaders.h>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment (lib, "uxtheme.lib")
#pragma comment(lib, "user32.lib")
#pragma warning(disable:4996)
using namespace Gdiplus;
#define FILE_OPEN 1
#define FILE_MENU_EXIT 3
#define MENU_HELP 4
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("Multi-Purpose Media Editor");
HINSTANCE hInst;
HMENU hMenu;
PWSTR filePath;
int flag = 0;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
void AddControls(HWND);
void OpenFileWindow(HWND);
void putImage(HDC, HWND);
std::wstring s2ws(const std::string&);
//Main Function for Windows Desktop Application
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
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 RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
hInst = hInstance;
DEVMODE settings;
EnumDisplaySettings(NULL, 0, &settings);
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL
);
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HRESULT hr;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
AddMenus(hWnd);
AddControls(hWnd);
hr = BufferedPaintInit();
break;
case WM_COMMAND:
switch (wParam)
{
case FILE_MENU_EXIT:
// File Menu Exit
DestroyWindow(hWnd);
break;
case FILE_OPEN:
OpenFileWindow(hWnd);
flag = 1;
InvalidateRect(hWnd, NULL, FALSE);
break;
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
/*Gdiplus::Graphics gf(screen);
Gdiplus::Bitmap jpgicon(L"jpg-icon.png");
Gdiplus::Bitmap pdficon(L"pdf-icon.png");
gf.DrawImage(&jpgicon, 10, 10);
gf.DrawImage(&pdficon, 900, 10);*/
if (flag)
{
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
//DrawText(screen, L"Multi-Purpose Media Editor", -1, &rc, DT_BOTTOM | DT_VCENTER | DT_SINGLELINE);
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
flag = 0;
}
EndPaint(hWnd, &ps); } break;
case WM_DESTROY:
BufferedPaintUnInit();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
void AddMenus(HWND hWnd)
{
hMenu = CreateMenu();
HMENU hFileMenu = CreateMenu();
HMENU hSubMenu = CreateMenu();
// File Open Submenu
/*AppendMenu(hSubMenu, MF_STRING, FILE_OPEN_JPG, s2ws("JPG").c_str());
AppendMenu(hSubMenu, MF_STRING, FILE_OPEN_PDF, s2ws("PDF").c_str());*/
// File Popup Menu
// (UINT_PTR)hSubMenu <- for submenu
AppendMenu(hFileMenu, MF_POPUP, FILE_OPEN, s2ws("Open").c_str());
AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, s2ws("Exit").c_str());
// Main Menu
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, s2ws("File").c_str());
AppendMenu(hMenu, MF_STRING, MENU_HELP, s2ws("Help").c_str());
SetMenu(hWnd, hMenu);
}
void AddControls(HWND hWnd)
{
// Static and Edit Controls
CreateWindowW(L"static", L"Multi-Purpose Media Editor", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, GetSystemMetrics(SM_CXSCREEN) / 2, 10, 180, 30, hWnd, NULL, NULL, NULL);
// Button on Window
//CreateWindowW(L"button", L"JPG Editor", WS_VISIBLE | WS_CHILD, 190, 150, 100, 30, hWnd, NULL, NULL, NULL);
//CreateWindowW(L"button", L"PDF Editor", WS_VISIBLE | WS_CHILD, 770, 150, 100, 30, hWnd, NULL, NULL, NULL);
CreateWindowW(L"button", L"Edit Image", WS_VISIBLE | WS_CHILD, GetSystemMetrics(SM_CXSCREEN) / 4, 3 * GetSystemMetrics(SM_CYSCREEN) / 4, 100, 30, hWnd, (HMENU)FILE_OPEN, NULL, NULL);
CreateWindowW(L"button", L"Edit PDF", WS_VISIBLE | WS_CHILD, 3 * GetSystemMetrics(SM_CXSCREEN) / 4, 3 * GetSystemMetrics(SM_CYSCREEN) / 4, 100, 30, hWnd, NULL, NULL, NULL);
}
void OpenFileWindow(HWND hWnd)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog* pFileOpen;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
// Show the Open dialog box.
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr))
{
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr))
{
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr))
{
char szBuffer[255];
WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
// JPG/JPEG/PNG
if (1)
{
filePath = pszFilePath;
}
// PDF
//else if ()
//{
//}
// Error MSG
else
{
MessageBox(NULL, L"Not a supported media!", L"Error", MB_OK);
}
//LoadImageW(hInst, pszFilePath, 0, 0, 0, LR_DEFAULTSIZE);
//MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
}
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(filePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
//RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
//RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
I have two icons (.ico files). A big 32x32 one and another small 16x16.
I'm trying to set the hIcon of my WNDCLASSEX to be the big one, and hIconSm to the smaller one. Yet I cannot for the life of me figure out how to do that! I first tried LoadIcon:
wndclass.hIcon = LoadIcon(instance, MAKEINTRESOURCE(IDI_SKELETON));
wndclass.hIconSm = LoadIcon(instance, MAKEINTRESOURCE(IDI_SKELETON_SM));
It always loads the same icon for both the top window bar and the taskbar. Same thing with LoadImage.
Here's all the codes:
Resource.h
#define IDI_SKELETON 1000
#define IDI_SKELETON_SM 1001
Skeleton.rc
#include "Resource.h"
IDI_SKELETON ICON "Skeleton.ico"
IDI_SKELETON_SM ICON "Skeleton_sm.ico"
WinMain.cpp
#include <windows.h>
#include "Resource.h"
LRESULT CALLBACK
HandleEvent(HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam)
{
switch(message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC dc;
RECT rect;
dc = BeginPaint(window, &ps);
GetClientRect(window, &rect);
DrawText(dc, TEXT("This is a test window"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(window, &ps);
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProc(window, message, wparam, lparam);
}
int CALLBACK
WinMain(HINSTANCE instance,
HINSTANCE previous,
LPSTR cmd,
int cmdshow)
{
WNDCLASSEX wndclass;
TCHAR classname[] = TEXT("24HoursClass");
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = HandleEvent;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = instance;
wndclass.hIcon = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_SKELETON), IMAGE_ICON,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
wndclass.hIconSm = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_SKELETON_SM), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = classname;
RegisterClassEx(&wndclass);
HWND window = CreateWindowA(classname, "24 Hours",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, instance, 0);
MSG msg;
while(GetMessage(&msg, window, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
What am I missing?
Any help is appreciated!
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;
}
I want to know which "FamilyName" was used by Windows to create a font with an unknown facename "Blah".
As you can see below, the font is created normally (WM_PAINT uses it to print the return value of the function GetOutlineTextMetric().
#include <windows.h>
#include <iostream>
LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
WNDCLASSEX wndclassx;
wndclassx.cbSize = sizeof(WNDCLASSEX);
wndclassx.style = CS_HREDRAW | CS_VREDRAW;
wndclassx.lpfnWndProc = WndProc;
wndclassx.cbClsExtra = 0;
wndclassx.cbWndExtra = 0;
wndclassx.hInstance = hInstance;
wndclassx.hIcon = nullptr;
wndclassx.hCursor = LoadCursor(nullptr, IDC_ARROW);
wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclassx.lpszMenuName = nullptr;
wndclassx.lpszClassName = L"WndProc";
wndclassx.hIconSm = nullptr;
if( !RegisterClassEx(&wndclassx) ) return 0;
HWND hWnd = CreateWindow(L"WndProc", nullptr, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hWnd, SW_NORMAL);
UpdateWindow(hWnd);
MSG msg;
while( GetMessage(&msg, nullptr, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Retorna msg.wParam
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
static HFONT s_hFont;
static int s_int = -1;
static TEXTMETRIC s_tm;
switch ( message )
{
case WM_CREATE:
{
HDC hDC;
if( !(hDC = CreateIC(L"Display", nullptr, nullptr, nullptr)) ) return -1;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Blah");
if( !(s_hFont = CreateFontIndirect(&lf)) )
{
DeleteDC(hDC);
return -1;
}
s_hFont = (HFONT)SelectObject(hDC, s_hFont);
GetTextMetrics(hDC, &s_tm);
// Call GetOutlineTextMetrics() with a null buffer address, to get the size of the buffer.
s_int = GetOutlineTextMetrics(hDC, 0, nullptr);
s_hFont = (HFONT)SelectObject(hDC, s_hFont);
DeleteDC(hDC);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
s_hFont = (HFONT)SelectObject(ps.hdc, s_hFont);
TextOut(ps.hdc, 20, 20, L"Value returned by GetOutlineTextMetrics() function", 50);
wchar_t buffer[4];
swprintf(buffer, 4, L"%3d", s_int);
TextOut(ps.hdc, 20 + 55 * s_tm.tmAveCharWidth, 20, buffer, 3);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(s_hFont);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
Output
Edit : there was an error in the code which I corrected. Instead of SelectObject(hDC, s_hFont) in WM_CREATE, I should have s_hFont = (HFONT)SelectObject(hDC, s_hFont). Didn't change the output though. But the final result is the same, that is, the function GetOutlineTextMetrics() continues returning 0.
My crystal ball suggests the font selected into the DC is not a TrueType font.
Some versions of MSDN say you can call GetLastError to find out why the function failed, but other (later?) versions of MSDN have that sentence removed.
GetOutlineTextMetrics() can only work on TrueType fonts. Problem is, you didn't ask for one. The font mapper has no reason to substitute your request with a TrueType font.
Solve your problem by insisting that the mapper always returns a TT font:
wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Blah");
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;