- UID
- 1
- 精华
- 积分
- 76365
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
作者:0xAA55
来源:http://www.0xaa55.com/thread-1417-1-1.html
转载请注明出处。
如图所示。这并不和VB的完全一样。它能显示图片,以及拉伸显示图片,除此以外,还能开启“自动重绘”模式。在自动重绘模式下用户需要通过调用函数取得hDC进行绘图操作。这样这东西就内置了一个画板。
头文件的代码:- #ifndef _PictureBoxHeader_
- #define _PictureBoxHeader_
- #include<Windows.h>
- //PictureBox的额外属性结构
- //读取方式:(PicBoxAttr_p)GetWindowLong(hPicBox,GWL_USERDATA);
- typedef struct
- {
- DWORD dwSign; //签名
- HINSTANCE hInst; //实例句柄
- HWND hWnd; //窗口句柄
- HBRUSH BkBrush; //背景色
- HDC hCtlDC; //控件HDC
- HDC hPicDC; //图像HDC
- HBITMAP hPicBmp; //图像
- LONG lPicW; //图像宽度
- LONG lPicH; //图像高度
- HDC hImgDC; //后台图像HDC
- HBITMAP hImgBmp; //后台图像
- void *pImgBits; //后台图像位图数据
- LONG lImgW; //后台图像宽度
- LONG lImgH; //后台图像镐度
- BOOL bStretch; //是否拉伸
- BOOL bAutoRedraw;//是否自动重绘
- }PicBoxAttr_t,*PicBoxAttr_p;
- //注册PictureBox窗口类
- ATOM WINAPI RegisterPictureBox();
- //创建PictureBox控件
- HWND WINAPI CreatePictureBox(int x,int y,int w,int h,HWND hParent,WORD ID);
- //加载PictureBox的图像
- BOOL WINAPI LoadPicture(HWND hWnd,TCHAR*szPicFile);
- //判断是否为PictureBox控件
- BOOL WINAPI IsPictureBox(HWND hWnd);
- //设置PictureBox控件是否拉伸图像
- void WINAPI SetPicBoxStretchMode(HWND hWnd,BOOL bStretch);
- //设置PictureBox控件是否自动重绘
- void WINAPI SetPicBoxAutoRedrawMode(HWND hWnd,BOOL bAutoRedraw);
- //取得PictureBox的绘图句柄
- HDC WINAPI GetPicBoxHDC(HWND hWnd);
- //显示PictureBox的图像
- void WINAPI RefreshPicBox(HWND hWnd);
- //设置PictureBox的边框样式
- void WINAPI SetPicBoxBorderMode(HWND hWnd,BOOL bShowBorder);
- //清屏
- void WINAPI ClearPicBoxImage(HWND hWnd);
- //删除图片框的图片
- void WINAPI DeletePicBoxPicture(HWND hWnd);
- #endif // !_PictureBoxHeader_
复制代码 实现部分的代码:- #include"picbox.h"
- static ATOM g_ClassAtom=0;
- const TCHAR g_szPicBoxClass[]=TEXT("PictureBox");
- const DWORD PicBoxSign=0x091C7B08;
- #define CalcPitch(w,b) ((((w)*(b)-1)/32+1)*4)
- //=============================================================================
- //函数:CreatePicBoxAttr
- //描述:创建PictureBox属性块
- //-----------------------------------------------------------------------------
- static
- PicBoxAttr_p CreatePicBoxAttr(HWND hWnd)
- {
- PicBoxAttr_p pAttr=(PicBoxAttr_p)malloc(sizeof(PicBoxAttr_t));
- if(pAttr)
- {
- memset(pAttr,0,sizeof(PicBoxAttr_t));
- pAttr->dwSign=PicBoxSign;
- pAttr->hInst=GetModuleHandle(NULL);
- pAttr->hWnd=hWnd;
- pAttr->BkBrush=(HBRUSH)(COLOR_BTNFACE+1);
- pAttr->hCtlDC=GetWindowDC(hWnd);
- }
- return pAttr;
- }
- //=============================================================================
- //函数:DeletePicBoxAttr
- //描述:删除PictureBox属性块
- //-----------------------------------------------------------------------------
- static
- void DeletePicBoxAttr(PicBoxAttr_p pAttr)
- {
- if(pAttr)
- {
- //释放控件HDC
- if(pAttr->hCtlDC)
- ReleaseDC(pAttr->hWnd,pAttr->hCtlDC);
-
- //删除图像
- if(pAttr->hPicBmp)DeleteObject(pAttr->hPicBmp);
- if(pAttr->hPicDC)DeleteDC(pAttr->hPicDC);
- //删除后台图像
- if(pAttr->hImgBmp)DeleteObject(pAttr->hImgBmp);
- if(pAttr->hImgDC)DeleteDC(pAttr->hImgDC);
- //释放内存
- free(pAttr);
- }
- }
- //=============================================================================
- //函数:SetupPicBoxImage
- //描述:重置PictureBox的后台图像
- //-----------------------------------------------------------------------------
- static
- BOOL SetupPicBoxImage(PicBoxAttr_p pAttr)
- {
- RECT rc;
- BITMAPINFOHEADER BMIF;
- HDC hWindowDC;
- HDC hNewDC=NULL;
- HBITMAP hNewBMP=NULL;
- void*pBits;
- //创建一个新的HDC和HBITMAP
- hWindowDC=GetWindowDC(pAttr->hWnd);
- hNewDC=CreateCompatibleDC(hWindowDC);
- ReleaseDC(pAttr->hWnd,hWindowDC);
- if(!hNewDC)
- return FALSE;
- GetClientRect(pAttr->hWnd,&rc);
- BMIF.biSize=sizeof(BMIF);
- BMIF.biWidth=rc.right-rc.left;
- BMIF.biHeight=rc.bottom-rc.top;
- BMIF.biPlanes=1;
- BMIF.biBitCount=24;
- BMIF.biCompression=0;
- BMIF.biSizeImage=CalcPitch(BMIF.biWidth,BMIF.biBitCount)*BMIF.biHeight;
- BMIF.biXPelsPerMeter=0;
- BMIF.biYPelsPerMeter=0;
- BMIF.biClrUsed=0;
- BMIF.biClrImportant=0;
- hNewBMP=CreateDIBSection(hNewDC,(BITMAPINFO*)&BMIF,DIB_PAL_COLORS,&pBits,
- NULL,0);
- if(!hNewBMP)
- goto Failed;
- SelectObject(hNewDC,hNewBMP);
- //填充为背景色,然后搬运旧的后台图像
- FillRect(hNewDC,&rc,pAttr->BkBrush);
- if(pAttr->hImgDC)
- {
- BitBlt(hNewDC,0,0,pAttr->lImgW,pAttr->lImgH,pAttr->hImgDC,0,0,SRCCOPY);
- DeleteDC(pAttr->hImgDC);
- }
- else if(pAttr->hPicDC)
- BitBlt(hNewDC,0,0,pAttr->lPicW,pAttr->lPicH,pAttr->hPicDC,0,0,SRCCOPY);
- if(pAttr->hImgBmp)
- DeleteObject(pAttr->hImgBmp);
- //替换为新的后台图像
- pAttr->lImgW=BMIF.biWidth;
- pAttr->lImgH=BMIF.biHeight;
- pAttr->hImgBmp=hNewBMP;
- pAttr->hImgDC=hNewDC;
- pAttr->pImgBits=pBits;
- return TRUE;
- Failed:
- if(hNewBMP)
- DeleteObject(hNewBMP);
- if(hNewDC)
- DeleteDC(hNewDC);
- return FALSE;
- }
- //=============================================================================
- //函数:LoadPicture
- //描述:加载PictureBox的图像
- //-----------------------------------------------------------------------------
- BOOL WINAPI LoadPicture(HWND hWnd,TCHAR*szPicFile)
- {
- PicBoxAttr_p pAttr;
- BITMAP bmp;
- if(IsPictureBox(hWnd))
- pAttr=(PicBoxAttr_p)GetWindowLongPtr(hWnd,GWL_USERDATA);
- else
- return FALSE;
- //创建HDC,然后清除之前加载过的图像
- if(!pAttr->hPicDC)
- {
- HDC hDC=GetWindowDC(hWnd);
- pAttr->hPicDC=CreateCompatibleDC(hDC);
- ReleaseDC(hWnd,hDC);
- }
- if(pAttr->hPicBmp)
- DeleteObject(pAttr->hPicBmp);
- //加载图像
- pAttr->hPicBmp=(HBITMAP)LoadImage(pAttr->hInst,szPicFile,IMAGE_BITMAP,0,0,
- LR_LOADFROMFILE|LR_CREATEDIBSECTION);
- if(!pAttr->hPicBmp)
- return FALSE;
- SelectObject(pAttr->hPicDC,pAttr->hPicBmp);
- GetObject(pAttr->hPicBmp,sizeof(bmp),&bmp);
- pAttr->lPicW=bmp.bmWidth;
- pAttr->lPicH=bmp.bmHeight;
- RefreshPicBox(hWnd);
- return TRUE;
- }
- //=============================================================================
- //函数:RefreshPicBox
- //描述:显示PictureBox的图像
- //-----------------------------------------------------------------------------
- void WINAPI RefreshPicBox(HWND hWnd)
- {
- RECT rc;
- GetClientRect(hWnd,&rc);
- InvalidateRect(hWnd,&rc,TRUE);
- }
- //=============================================================================
- //函数:PicBoxWndProc
- //描述:PictureBox的消息处理函数
- //-----------------------------------------------------------------------------
- static
- LRESULT CALLBACK PicBoxWndProc(HWND hWnd,UINT Msg,WPARAM wp,LPARAM lp)
- {
- PicBoxAttr_p pAttr=NULL;
- switch(Msg)
- {
- case WM_CREATE:
- pAttr=CreatePicBoxAttr(hWnd);
- if(pAttr)
- SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pAttr);
- else
- return-1;
- break;
- case WM_COMMAND:
- hWnd=GetParent(hWnd);
- if(hWnd)
- return SendMessage(hWnd,Msg,wp,lp);
- break;
- case WM_PAINT:
- pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- if(pAttr)
- {
- PAINTSTRUCT ps;
- HDC hDC;
- hDC=BeginPaint(hWnd,&ps);
- if(pAttr->bAutoRedraw)//自动重绘的话,绘制后台图像
- {
- if(!pAttr->hImgDC || !pAttr->hImgBmp)
- SetupPicBoxImage(pAttr);
- BitBlt(hDC,0,0,pAttr->lImgW,pAttr->lImgH,
- pAttr->hImgDC,0,0,SRCCOPY);
- }
- else//否则绘制图像
- {
- RECT rc;
- GetClientRect(hWnd,&rc);
- if(pAttr->bStretch)
- {
- SetStretchBltMode(hDC,HALFTONE);
- StretchBlt(hDC,
- rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,
- pAttr->hPicDC,
- 0,0,pAttr->lPicW,pAttr->lPicH,SRCCOPY);
- }
- else
- BitBlt(hDC,rc.left,rc.top,pAttr->lPicW,pAttr->lPicH,
- pAttr->hPicDC,0,0,SRCCOPY);
- }
- EndPaint(hWnd,&ps);
- }
- break;
- case WM_DESTROY:
- pAttr=(PicBoxAttr_p)GetWindowLongPtr(hWnd,GWL_USERDATA);
- if(pAttr)
- DeletePicBoxAttr(pAttr);
- SetWindowLongPtr(hWnd,GWL_USERDATA,0);
- break;
- default:
- return DefWindowProc(hWnd,Msg,wp,lp);
- }
- return 0;
- }
- //=============================================================================
- //函数:RegisterPictureBox
- //描述:注册PictureBox窗口类
- //-----------------------------------------------------------------------------
- ATOM WINAPI RegisterPictureBox()
- {
- WNDCLASSEX WCEx=
- {
- sizeof(WNDCLASSEX),
- 0,
- PicBoxWndProc,
- 0,
- 0,
- GetModuleHandle(NULL),
- NULL,
- LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)),
- (HBRUSH)(COLOR_BTNFACE+1),
- NULL,
- g_szPicBoxClass,
- NULL
- };
- return g_ClassAtom=RegisterClassEx(&WCEx);
- }
- //=============================================================================
- //函数:CreatePictureBox
- //描述:创建PictureBox控件
- //-----------------------------------------------------------------------------
- HWND WINAPI CreatePictureBox(int x,int y,int w,int h,HWND hParent,WORD ID)
- {
- return CreateWindowEx(0,MAKEINTATOM(g_ClassAtom),NULL,
- WS_CHILD|WS_VISIBLE|WS_BORDER,x,y,w,h,
- hParent,(HMENU)ID,GetModuleHandle(NULL),NULL);
- }
- //=============================================================================
- //函数:IsPictureBox
- //描述:判断是否为PictureBox控件
- //-----------------------------------------------------------------------------
- BOOL WINAPI IsPictureBox(HWND hWnd)
- {
- # define nPicBox (sizeof(g_szPicBoxClass)/sizeof(TCHAR)-1)
- TCHAR szPicBoxClass[nPicBox+2];
- //首先判断窗口类
- if(GetClassName(hWnd,szPicBoxClass,nPicBox+2) == nPicBox)
- {
- if(!lstrcmp(szPicBoxClass,g_szPicBoxClass))
- {
- //然后判断附加信息
- PicBoxAttr_p pAttr
- =(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- if(!IsBadReadPtr(pAttr,sizeof(PicBoxAttr_t)))
- {
- if(pAttr->dwSign==PicBoxSign)
- return TRUE;
- }
- }
- }
-
- return FALSE;
- # undef nPicBox
- }
- //=============================================================================
- //函数:SetPicBoxStretchMode
- //描述:设置PictureBox控件是否拉伸图像
- //-----------------------------------------------------------------------------
- void WINAPI SetPicBoxStretchMode(HWND hWnd,BOOL bStretch)
- {
- if(IsPictureBox(hWnd))
- {
- PicBoxAttr_p pAttr;
- pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- pAttr->bStretch=bStretch;
- //强制重绘
- RefreshPicBox(hWnd);
- }
- }
- //=============================================================================
- //函数:SetPicBoxAutoRedrawMode
- //描述:设置PictureBox控件是否自动重绘
- //-----------------------------------------------------------------------------
- void WINAPI SetPicBoxAutoRedrawMode(HWND hWnd,BOOL bAutoRedraw)
- {
- if(IsPictureBox(hWnd))
- {
- PicBoxAttr_p pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- pAttr->bAutoRedraw=bAutoRedraw;
- if(bAutoRedraw)
- SetupPicBoxImage(pAttr);
- }
- }
- //=============================================================================
- //函数:GetPicBoxHDC
- //描述:取得PictureBox的绘图句柄
- //-----------------------------------------------------------------------------
- HDC WINAPI GetPicBoxHDC(HWND hWnd)
- {
- if(IsPictureBox(hWnd))
- {
- PicBoxAttr_p pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- if(pAttr->bAutoRedraw)
- return pAttr->hImgDC;
- else
- return pAttr->hCtlDC;
- }
- return NULL;
- }
- //=============================================================================
- //函数:SetPicBoxBorderMode
- //描述:设置PictureBox的边框样式
- //-----------------------------------------------------------------------------
- void WINAPI SetPicBoxBorderMode(HWND hWnd,BOOL bShowBorder)
- {
- if(IsPictureBox(hWnd))
- {
- if(bShowBorder)
- SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE)|WS_BORDER);
- else
- SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE)&~WS_BORDER);
- RefreshPicBox(hWnd);
- }
- }
- //=============================================================================
- //函数:ClearPicBoxImage
- //描述:清屏
- //-----------------------------------------------------------------------------
- void WINAPI ClearPicBoxImage(HWND hWnd)
- {
- if(IsPictureBox(hWnd))
- {
- PicBoxAttr_p pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- if(pAttr->bAutoRedraw && pAttr->hImgDC)
- {
- RECT rc;
- GetClientRect(hWnd,&rc);
- FillRect(pAttr->hImgDC,&rc,pAttr->BkBrush);
- if(pAttr->hPicDC && pAttr->hPicBmp)
- BitBlt(pAttr->hImgDC,0,0,pAttr->lPicW,pAttr->lPicH,
- pAttr->hPicDC,0,0,SRCCOPY);
- }
- RefreshPicBox(hWnd);
- }
- }
- //=============================================================================
- //函数:DeletePicBoxPicture
- //描述:删除图片框的图片
- //-----------------------------------------------------------------------------
- void WINAPI DeletePicBoxPicture(HWND hWnd)
- {
- if(IsPictureBox(hWnd))
- {
- PicBoxAttr_p pAttr=(PicBoxAttr_p)GetWindowLong(hWnd,GWL_USERDATA);
- if(pAttr->bAutoRedraw)
- {
- RECT rc;
- GetClientRect(hWnd,&rc);
- FillRect(pAttr->hImgDC,&rc,pAttr->BkBrush);
- }
- DeleteObject(pAttr->hPicBmp);pAttr->hPicBmp=NULL;
- DeleteDC(pAttr->hPicDC);pAttr->hPicDC=NULL;
- RefreshPicBox(hWnd);
- }
- }
复制代码 引用的例子:- #include<Windows.h>
- #include"picbox.h"
- LRESULT CALLBACK WndProc(HWND hWnd,UINT Msg,WPARAM wp,LPARAM lp)
- {
- switch(Msg)
- {
- default:
- return DefWindowProc(hWnd,Msg,wp,lp);
- case WM_CREATE:
- RegisterPictureBox();
- do
- {
- HWND hPicBox1,hPicBox2;
- hPicBox1=CreatePictureBox(0,0,300,300,hWnd,1);
- LoadPicture(hPicBox1,TEXT("tex1.bmp"));
- hPicBox2=CreatePictureBox(300,0,400,400,hWnd,1);
- LoadPicture(hPicBox2,TEXT("tex1.bmp"));
- SetPicBoxStretchMode(hPicBox2,TRUE);
- }while(0);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- }
- return 0;
- }
- int APIENTRY WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szCmd,int nCmd)
- {
- WNDCLASSEX WCEx={sizeof(WNDCLASSEX),0,WndProc,0,0,hInst,LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION)),LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)),(HBRUSH)COLOR_BTNFACE,NULL,TEXT("tutpicbox"),NULL};//窗口类
- MSG msg;
- HWND hWnd=CreateWindowEx(0,MAKEINTATOM(RegisterClassEx(&WCEx)),TEXT("tutpicbox"),WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL);//窗口句柄
- ShowWindow(hWnd,nCmd);
- UpdateWindow(hWnd);
- while(GetMessage(&msg,NULL,0,0))//消息循环
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
复制代码 BIN:
picboxbin.7z
(20.59 KB, 下载次数: 8)
SRC:
tutpicbox.7z
(25.49 KB, 下载次数: 24)
|
|