用WinAPI实现一个图片查看器:一个打开按钮,点击后打开一个打开文件对话框,打开选中的png文件显示在屏幕上,并可以用鼠标滚轮调整大小,并添加多彩画笔编辑功能,编辑完后点击保存按钮用保存文件对话框保存为png
时间: 2024-04-16 19:28:01 浏览: 20
好的,根据您的要求,我将为您提供一个基本的实现框架。以下是一个使用WinAPI实现图片查看器的示例代码:
```cpp
#include <windows.h>
#include <commctrl.h>
#include <gdiplus.h>
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "gdiplus.lib")
// 全局变量
HWND g_hWnd;
HWND g_hButtonOpen;
HWND g_hButtonSave;
HWND g_hImage;
HBITMAP g_hBitmap;
HPEN g_hPen;
// 函数声明
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void OpenFile();
void SaveFile();
void Draw(HWND hWnd, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// 初始化公共控件
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icex);
// 初始化GDI+
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// 创建主窗口
HWND hWnd;
WNDCLASSEX wcex;
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(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"ImageViewer";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wcex);
g_hWnd = hWnd = CreateWindowEx(0, L"ImageViewer", L"图片查看器", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
// 创建打开按钮
g_hButtonOpen = CreateWindowEx(0, L"BUTTON", L"打开", WS_CHILD | WS_VISIBLE,
10, 10, 80, 30, hWnd, NULL, hInstance, NULL);
// 创建保存按钮
g_hButtonSave = CreateWindowEx(0, L"BUTTON", L"保存", WS_CHILD | WS_VISIBLE,
100, 10, 80, 30, hWnd, NULL, hInstance, NULL);
EnableWindow(g_hButtonSave, FALSE);
// 创建显示图片的静态控件
g_hImage = CreateWindowEx(0, L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP,
10, 50, 780, 540, hWnd, NULL, hInstance, NULL);
// 显示窗口
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// 释放GDI+
Gdiplus::GdiplusShutdown(gdiplusToken);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
if (LOWORD(wParam) == (WORD)g_hButtonOpen)
{
OpenFile();
}
else if (LOWORD(wParam) == (WORD)g_hButtonSave)
{
SaveFile();
}
break;
case WM_MOUSEWHEEL:
if (g_hBitmap != NULL)
{
short zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
int width, height;
GetClientRect(g_hImage, NULL);
width = LOWORD(lParam);
height = HIWORD(lParam);
if (zDelta > 0) // 向上滚动
{
width += 10;
height += 10;
}
else // 向下滚动
{
width -= 10;
height -= 10;
}
SetWindowPos(g_hImage, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER);
}
break;
case WM_LBUTTONDOWN:
case WM_MOUSEMOVE:
if (g_hBitmap != NULL)
{
Draw(hWnd, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
void OpenFile()
{
OPENFILENAME ofn;
wchar_t szFile[MAX_PATH] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = g_hWnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"PNG文件\0*.png\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn))
{
Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(szFile);
if (bitmap->GetLastStatus() == Gdiplus::Ok)
{
if (g_hBitmap != NULL)
{
DeleteObject(g_hBitmap);
}
g_hBitmap = (HBITMAP)bitmap->GetHBITMAP();
SendMessage(g_hImage, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_hBitmap);
EnableWindow(g_hButtonSave, TRUE);
}
delete bitmap;
}
}
void SaveFile()
{
OPENFILENAME ofn;
wchar_t szFile[MAX_PATH] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = g_hWnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"PNG文件\0*.png\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn))
{
Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(g_hBitmap, NULL);
if (bitmap->GetLastStatus() == Gdiplus::Ok)
{
bitmap->Save(szFile, &Gdiplus::ImageFormatPNG);
}
delete bitmap;
}
}
void Draw(HWND hWnd, LPARAM lParam)
{
HDC hdc = GetDC(hWnd);
int x = LOWORD(lParam);
int y = HIWORD(lParam);
if (GetAsyncKeyState(VK_LBUTTON) & 0x8000)
{
if (g_hPen == NULL)
{
g_hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
}
SelectObject(hdc, g_hPen);
MoveToEx(hdc, x, y, NULL);
LineTo(hdc, x, y);
}
ReleaseDC(hWnd, hdc);
}
```
请注意,上述代码仅提供了一个基本的框架,您可能需要根据自己的需求进行修改和完善。此示例使用了GDI+库来加载和保存图片,并使用GDI函数进行绘制。在编译时,请确保已添加所需的库文件并设置好编译器的附加包含目录。
希望这可以帮助到您!如果您有任何更多问题,请随时提问。