// Paint_001.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Paint_001.h"
#include<vector>
#include<string.h>
#include<iostream>
using namespace std;
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef UNICODE
#ifndef TSTRING
#define TSTRING std::wstring
#endif
#else
#ifndef TSTRING
#define TSTRING std::string
#endif
#endif
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_PAINT_001, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PAINT_001));
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望
// 此代码与添加到 Windows 95 中的“RegisterClassEx”
// 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
// 这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
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(hInstance, MAKEINTRESOURCE(IDI_PAINT_001));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PAINT_001);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
//====================================save====================================//
BOOL WriteBmp(const TSTRING &strFile,HDC hdc);
#pragma comment(lib,"Msimg32.lib");
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static POINT posStart;
static POINT posCur;
static BOOL bMouseDown = FALSE;
static HPEN hPen = NULL;
static int iRight ,iBottom;
static RECT rectClient;
static HDC hPaintDc;
static HDC hOrignalDc = NULL;
static HBITMAP hPaintBit;
static HBITMAP hOriginalBit;
static HBRUSH hBrush;
static int cx;
static int cy;
BITMAP * pGlobalBit;
BITMAP bitmap;
RECT reErase;
HDC hdcTemp;
RECT re;
HDC test;
static char acName[100]="jietiebanfuzhi";
char strNum[20];
static int num =0;
string str;
HGLOBAL hGoloble;
switch (message)
{
case WM_CREATE:
hPen = CreatePen(PS_DASHDOTDOT,4,RGB(155,155,155));
rectClient.left = 0;
rectClient.top = 0;
hdcTemp = GetDC(hWnd);
hOrignalDc = CreateCompatibleDC(hdcTemp);
hPaintDc = CreateCompatibleDC(hdcTemp);
char* pPast;
SelectObject(hPaintDc,hPen);
// hBrush =(HBRUSH) GetStockObject(NULL_BRUSH);
//SelectObject(hPaintDc,hBrush);
ReleaseDC(hWnd,hdcTemp);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_SIZE: //获得大小可以写在这里,一些静态变量的复制,就别放在这里了。负责麻烦、
cx = LOWORD(lParam);
cy = HIWORD(lParam);
OutputDebugStringA("size\n");
rectClient.right = cx;
rectClient.bottom = cy;
/*
cx = LOWORD(lParam);
cy = HIWORD(lParam);
UpdateWindow(hWnd);
SendMessage(hWnd,WM_PAINT,NULL,NULL);
OutputDebugStringA("size\n");
rectClient.right = LOWORD(lParam);
rectClient.bottom = HIWORD(lParam);
/*
if(hPaintBit !=NULL)
{
DeleteObject(hPaintBit);
}
if(hOriginalBit !=NULL)
{
DeleteObject(hOriginalBit);
}
hdcTemp = GetDC(hWnd);
hOriginalBit = CreateCompatibleBitmap(hdcTemp,rectClient.right,rectClient.bottom);
hPaintBit = CreateCompatibleBitmap(hdcTemp,rectClient.right,rectClient.bottom);
SelectObject(hPaintDc,hPaintBit);
SelectObject(hOrignalDc,hOriginalBit);
PatBlt (hPaintDc,0,0,rectClient.right,rectClient.bottom,PATCOPY);
PatBlt(hOrignalDc,0,0,rectClient.right,rectClient.bottom,PATCOPY);
ReleaseDC(hWnd,hdcTemp);
test = GetDC(NULL);
//StretchBlt(hOrignalDc,0,0,rectClient.right,rectClient.bottom,test,0,0,rectClient.right,rectClient.bottom,SRCCOPY);
ReleaseDC(hWnd,test);
*/
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
//SelectObject(hdc,hPen);
//Rectangle(hdc,posStart.x,posStart.y,posCur.x,posCur.y);
//全部重画
if(ps.rcPaint.left == 0 && ps.rcPaint.right == rectClient.right && ps.rcPaint.top==0 && ps.rcPaint.bottom == rectClient.bottom)
{
//全部无效
if(hOriginalBit != NULL)
StretchBlt(hdc,0,0,cx,cy,hOrignalDc,0,0,rectClient.right,rectClient.bottom,SRCCOPY);
//=======================重新复制GDI=============================//
if(hPaintBit !=NULL)
{
DeleteObject(hPaintBit);
}
if(hOriginalBit !=NULL)
{
DeleteObject(hOriginalBit);
}
hOriginalBit = CreateCompatibleBitmap(hdc,rectClient.right,rectClient.bottom);
hPaintBit = CreateCompatibleBitmap(hdc,rectClient.right,rectClient.bottom);
SelectObject(hPaintDc,hPaintBit);
SelectObject(hOrignalDc,hOriginalBit);
PatBlt (hPaintDc,0,0,rectClient.right,rectClient.bottom,PATCOPY);
PatBlt(hOrignalDc,0,0,rectClient.right,rectClient.bottom,PATCOPY);
//复制保存的背景
BitBlt(hOrignalDc,0,0,cx,cy,hdc,0,0,SRCCOPY);
OutputDebugStringA("redraw\n");
}
else
{
//StretchBlt(hdc,0,0,rectClient.right,rectClient.bottom,hOrignalDc,0,0,rectClient.right,rectClient.bottom,SRCCOPY);
// BitBlt(hdc,0,0,rectClient.right,rectClient.bottom,hPaintDc,0,0,SRCCOPY);
// BitBlt(hdc,0,0,rectClient.right,rectClient.bottom,hOrignalDc,0,0,SRCCOPY);
//StretchBlt(hdc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,hOrignalDc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,SRCCOPY);
StretchBlt(hdc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,hOrignalDc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,SRCCOPY);
//这里很重要,因为我们这里用的双缓冲,不是直接在屏幕上画的。Rectangle是区域填充函数,内部默认是背景色填充的,因此我背景色透明贴图
TransparentBlt(hdc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,hPaintDc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,RGB(255,255,255));
// StretchBlt(hdc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,hOrignalDc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,SRCCOPY);
// StretchBlt(hOrignalDc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,hdc,posStart.x,posStart.y,posCur.x-posStart.x,posCur.y-posStart.y,SRCCOPY);
}
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN:
SetCapture(hWnd);//这里扑捉鼠标防治出去
bMouseDown = true;
posStart.x = LOWORD(lParam);
posStart.y = HIWORD(lParam);
iRight = posStart.x;
iBottom = posStart.y;
break;
case WM_MOUSEMOVE:
if(bMouseDown==TRUE)
{
posCur.x = LOWORD(lParam);
posCur.y = HIWORD(lParam);
if(posCur.x > iRight)//这里很重要,捕捉每次鼠标拖拽的最大范围,设为无效区。避免外围的线条
{
iRight =posCur.x;
}
if(posCur.y > iBottom)
{
iBottom = posCur.y;
}
reErase.left = posStart.x;
reErase.right = iRight;
reErase.top = posStart.y;
reErase.bottom = iBottom;
PatBlt(hPaintDc,reErase.left,reErase.top,reErase.right - reErase.left,reErase.bottom-reErase.top,PATCOPY);
//PatBlt (hPaintDc,0,0,rectClient.right,rectClient.bottom,PATCOPY);
Rectangle(hPaintDc,posStart.x,posStart.y,posCur.x,posCur.y);
InvalidateRect(hWnd,&reErase,TRUE);
}
break;
case WM_LBUTTONUP:
ReleaseCapture();//释放扑捉
bMouseDown = false;
posCur.x = LOWORD(lParam);
posCur.y = HIWORD(lParam);
if(posCur.x > iRight)
{
iRight =posCur.x;
}
if(posCur.y > iBottom)
{
iBottom = posCur.y;
}
reErase.left = posStart.x;
reErase.right = iRight;
reErase.top = posStart.y;
reErase.bottom = iBottom;
hdcTemp = GetDC(hWnd);
if(FALSE== BitBlt(hOrignalDc,0,0,rectClient.right,rectClient.bottom,hdcTemp,0,0,SRCCOPY) )
{
OutputDebugStringA("failed\n");
}
ReleaseDC(hWnd,hdcTemp);
InvalidateRect(hWnd,&reErase,TRUE);
OutputDebugStringA("up\n");
break;
case WM_DESTROY:
DeleteObject(hPen);
DeleteObject(hPaintBit);
DeleteObject(hOriginalBit);
// DeleteObject(hBrush);
DeleteDC(hPaintDc);
DeleteDC(hOrignalDc);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
//============================================save pic======================================//
BOOL WriteBmp(const TSTRING &strFile,HDC hdc);
BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);
BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);
BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg)
{
BITMAPINFOHEADER bmInfoHeader = {0};
bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfoHeader.biWidth = sizeImg.cx;
bmInfoHeader.biHeight = sizeImg.cy;
bmInfoHeader.biPlanes = 1;
bmInfoHeader.biBitCount = 24;
//Bimap file header in order to write bmp file
BITMAPFILEHEADER bmFileHeader = {0};
bmFileHeader.bfType = 0x4d42; //bmp
bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
HANDLE hFile = CreateFileA(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwWrite = 0;
WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
CloseHandle(hFile);
return TRUE;
}
BOOL WriteBmp(const TSTRING &strFile,HDC hdc)
{
int iWidth = GetDeviceCaps(hdc,HORZRES);
int iHeight = GetDeviceCaps(hdc,VERTRES);
RECT rcDC = {0,0,iWidth,iHeight};
return WriteBmp(strFile,hdc,rcDC);
}
BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC)
{
BOOL bRes = FALSE;
BITMAPINFO bmpInfo = {0};
BYTE *pData = NULL;
SIZE sizeImg = {0};
HBITMAP hBmp = NULL;
std::vector<BYTE> vtData;
HGDIOBJ hOldObj = NULL;
HDC hdcMem = NULL;
//Initilaize the bitmap information
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;
bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
//Create the compatible DC to get the data
hdcMem = CreateCompatibleDC(hdc);
if(hdcMem == NULL)
{
goto EXIT;
}
//Get the data from the memory DC
hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
if(hBmp == NULL)
{
goto EXIT;
}
hOldObj = SelectObject(hdcMem, hBmp);
//Draw to the memory DC
sizeImg.cx = bmpInfo.bmiHeader.biWidth;
sizeImg.cy = bmpInfo.bmiHeader.biHeight;
StretchBlt(hdcMem,
0,
0,
sizeImg.cx,
sizeImg.cy,
hdc,
rcDC.left,
rcDC.top,
rcDC.right - rcDC.left + 1,
rcDC.bottom - rcDC.top + 1,
SRCCOPY);
vtData.resize(sizeImg.cx * sizeImg.cy * 3);
memcpy(&vtData[0],pData,vtData.size());
bRes = WriteBmp(strFile,vtData,sizeImg);
SelectObject(hdcMem, hOldObj);
EXIT:
if(hBmp != NULL)
{
DeleteObject(hBmp);
}
if(hdcMem != NULL)
{
DeleteDC(hdcMem);
}
return bRes;
}
Win32 绘制矩形2
最新推荐文章于 2023-01-29 16:54:36 发布