这段时间在研究直接写屏的方法.
此问题的起因是: 在 iMX31(WinCE 5.0)上, 屏的分辨为: 800*480. 调用 BitBlt() API 函数画一整屏的动作, 竟然需要 120ms 左右; 同样的程序, 在 Prima 上只需要 20ms 以内的时间.
直接写屏, 需要用到以下两个主要的函数: CreateDC(TEXT("DISPLAY"),......) 和 CreateDIBSection().
1) CreateDC(TEXT("DISPLAY"),......) 的用法比较简单, 参考 MSDN 就可以很容易的搞定.
2) CreateDIBSection() API 函数的使用, 花了我一些时间. 因为以前没有用过它, 所以将其使用的方法记录如下:
1 { 2 HBITMAP hDIBitmap; 3 LPBYTE lpBitmapBits; 4 BITMAPINFO DriectBmp; 5 6 ZeroMemory(&DriectBmp,sizeof(BITMAPINFO)); 7 DriectBmp.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 8 DriectBmp.bmiHeader.biWidth = 800; 9 DriectBmp.bmiHeader.biHeight = 480; 10 DriectBmp.bmiHeader.biPlanes = 1; 11 DriectBmp.bmiHeader.biBitCount = 16; 12 HDC dcDirect = CreateCompatibleDC(dcBuf); 13 14 // 建立 hDIBitmap, dcDirect, 和 lpBitmapBits 之间的关系. 15 // 通过 DC 操作向 dcDirect 中写入图形数据, 从 lpBitmapBits 中取得内存数据, 进行内存 Copy 操作, 直接写向显存. 16 hDIBitmap = CreateDIBSection(dcDirect, (BITMAPINFO *)&DriectBmp, 17 DIB_RGB_COLORS, (void **)&lpBitmapBits, NULL, 0); 18 if(NULL != hDIBitmap) 19 { 20 HGDIOBJ OldBitmap = SelectObject(dcDirect, hDIBitmap); 21 22 BitBlt(dcDirect,0,0,800,480,dcBuf,0,0,SRCCOPY); 23 24 CopyMemory(gpbFrameAddress,lpBitmapBits,800 * 480 * 2); 25 26 SelectObject(dcDirect,OldBitmap); 27 } 28 29 DeleteObject(hDIBitmap); 30 DeleteDC(dcDirect); 31 }
在研究此问题的过程中, 在 CSDN 上找到一个很好的资源, 也记录在自己这里:
http://topic.csdn.net/u/20090629/09/00b25d0d-d461-47dc-88ad-0e2131a5abc7.html
并转载其中关键的代码如下:
1 #include "stdafx.h" 2 #include "CopyScreen.h" 3 #include <windows.h> 4 #include <commctrl.h> 5 #include"Jpeg.h" 6 #define MAX_LOADSTRING 100 7 8 // 全局变量: 9 HINSTANCE g_hInst; // 当前实例 10 HWND g_hWndMenuBar; // 菜单栏句柄 11 12 // 此代码模块中包含的函数的前向声明: 13 ATOM MyRegisterClass(HINSTANCE, LPTSTR); 14 BOOL InitInstance(HINSTANCE, int); 15 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 16 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 17 18 int WINAPI WinMain(HINSTANCE hInstance, 19 HINSTANCE hPrevInstance, 20 LPTSTR lpCmdLine, 21 int nCmdShow) 22 { 23 MSG msg; 24 25 // 执行应用程序初始化: 26 if (!InitInstance(hInstance, nCmdShow)) 27 { 28 return FALSE; 29 } 30 31 HACCEL hAccelTable; 32 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_COPYSCREEN)); 33 34 // 主消息循环: 35 while (GetMessage(&msg, NULL, 0, 0)) 36 { 37 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 38 { 39 TranslateMessage(&msg); 40 DispatchMessage(&msg); 41 } 42 } 43 44 return (int) msg.wParam; 45 } 46 47 // 48 // 函数: MyRegisterClass() 49 // 50 // 目的: 注册窗口类。 51 // 52 // 注释: 53 // 54 ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) 55 { 56 WNDCLASS wc; 57 58 wc.style = CS_HREDRAW | CS_VREDRAW; 59 wc.lpfnWndProc = WndProc; 60 wc.cbClsExtra = 0; 61 wc.cbWndExtra = 0; 62 wc.hInstance = hInstance; 63 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_COPYSCREEN)); 64 wc.hCursor = 0; 65 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 66 wc.lpszMenuName = 0; 67 wc.lpszClassName = szWindowClass; 68 69 return RegisterClass(&wc); 70 } 71 72 // 73 // 函数: InitInstance(HINSTANCE, int) 74 // 75 // 目的: 保存实例句柄并创建主窗口 76 // 77 // 注释: 78 // 79 // 在此函数中,我们在全局变量中保存实例句柄并 80 // 创建和显示主程序窗口。 81 // 82 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 83 { 84 HWND hWnd; 85 TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 86 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 87 88 g_hInst = hInstance; // 将实例句柄存储在全局变量中 89 90 // 在应用程序初始化期间,应调用一次 SHInitExtraControls 以初始化 91 // 所有设备特定控件,例如,CAPEDIT 和 SIPPREF。 92 SHInitExtraControls(); 93 94 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 95 LoadString(hInstance, IDC_COPYSCREEN, szWindowClass, MAX_LOADSTRING); 96 97 //如果它已经在运行,则将焦点置于窗口上,然后退出 98 hWnd = FindWindow(szWindowClass, szTitle); 99 if (hWnd) 100 { 101 // 将焦点置于最前面的子窗口 102 // “| 0x00000001”用于将所有附属窗口置于前台并 103 // 激活这些窗口。 104 SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001)); 105 return 0; 106 } 107 108 if (!MyRegisterClass(hInstance, szWindowClass)) 109 { 110 return FALSE; 111 } 112 113 hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, 114 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); 115 116 if (!hWnd) 117 { 118 return FALSE; 119 } 120 121 // 使用 CW_USEDEFAULT 创建主窗口时,将不会考虑菜单栏的高度(如果创建了一个 122 // 菜单栏)。因此,我们要在创建窗口后调整其大小 123 // 如果菜单栏存在 124 if (g_hWndMenuBar) 125 { 126 RECT rc; 127 RECT rcMenuBar; 128 129 GetWindowRect(hWnd, &rc); 130 GetWindowRect(g_hWndMenuBar, &rcMenuBar); 131 rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top); 132 133 MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE); 134 } 135 136 ShowWindow(hWnd, nCmdShow); 137 UpdateWindow(hWnd); 138 139 140 return TRUE; 141 } 142 143 HBITMAP CopyScreenToBitmap(int &nWidth,int &nHeight) 144 { 145 // 屏幕和内存设备描述表 146 HDC hScrDC, hMemDC; 147 // 位图句柄 148 HBITMAP hBitmap, hOldBitmap; 149 // 屏幕分辨率 150 int xScrn, yScrn; 151 152 //为屏幕创建设备描述表 153 hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); 154 //为屏幕设备描述表创建兼容的内存设备描述表 155 hMemDC = CreateCompatibleDC(hScrDC); 156 // 获得屏幕分辨率 157 xScrn = GetDeviceCaps(hScrDC, HORZRES); 158 yScrn = GetDeviceCaps(hScrDC, VERTRES); 159 160 //存储屏幕的长宽 161 nWidth = xScrn; 162 nHeight = yScrn; 163 164 // 创建一个与屏幕设备描述表兼容的位图 165 hBitmap = CreateCompatibleBitmap(hScrDC, xScrn, yScrn); 166 // 把新位图选到内存设备描述表中 167 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 168 // 把屏幕设备描述表拷贝到内存设备描述表中 169 BitBlt(hMemDC, 0, 0, xScrn,yScrn,hScrDC, 0, 0, SRCCOPY); 170 //得到屏幕位图的句柄 171 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); 172 //清除 173 DeleteDC(hScrDC); 174 DeleteDC(hMemDC); 175 // 返回位图句柄 176 return hBitmap; 177 } 178 179 int Save16BitmapToFile(HBITMAP hBitmap,LPCTSTR lpFileName)//将截屏所得保存为16位的图片 180 { 181 HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); 182 HDC hOffDC=CreateCompatibleDC(hDC); 183 SelectObject(hOffDC,hBitmap); 184 185 BITMAP Bitmap; 186 GetObject(hBitmap,sizeof(BITMAP),&Bitmap); 187 188 HANDLE fh=CreateFile(lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, 189 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); 190 if(fh == INVALID_HANDLE_VALUE ) 191 return FALSE; 192 193 BITMAPFILEHEADER bfh; 194 memset(&bfh,0,sizeof(bfh)); 195 bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/; 196 bfh.bfSize= sizeof(bfh)+2*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER); 197 bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER); 198 DWORD dwWritten=0; 199 WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL); 200 BITMAPINFOHEADER bih; 201 memset(&bih,0,sizeof(bih)); 202 bih.biSize=sizeof(bih); 203 bih.biWidth=Bitmap.bmWidth; 204 bih.biHeight=Bitmap.bmHeight; 205 bih.biPlanes=1; 206 bih.biBitCount=16; 207 208 if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL) ) 209 { 210 return FALSE; 211 } 212 213 BITMAPINFO bitmapInfo; 214 memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO) ); 215 bitmapInfo.bmiHeader=bih; 216 217 HDC hMemDC=CreateCompatibleDC(hDC); 218 BYTE *m_lpBitBmp=new BYTE[bfh.bfSize-sizeof(BITMAPFILEHEADER)]; 219 HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp, 220 NULL,0); 221 if(hDibBitmap != 0) 222 { 223 ::SelectObject(hMemDC,hDibBitmap); 224 BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY); 225 WriteFile(fh,m_lpBitBmp,bfh.bfSize-sizeof(BITMAPFILEHEADER),&dwWritten,NULL); 226 } 227 228 DeleteObject(hDibBitmap); 229 DeleteDC(hDC); 230 DeleteDC(hMemDC); 231 232 CloseHandle(fh); 233 234 return 1; 235 236 } 237 238 int Save24BitmapToFile(HBITMAP hBitmap,LPCTSTR lpFileName)//将截屏所得保存为24位的图片 239 { 240 HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); 241 HDC hOffDC=CreateCompatibleDC(hDC); 242 SelectObject(hOffDC,hBitmap); 243 244 BITMAP Bitmap; 245 GetObject(hBitmap,sizeof(BITMAP),&Bitmap); 246 247 HANDLE fh=CreateFile(lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, 248 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); 249 if(fh == INVALID_HANDLE_VALUE ) 250 return FALSE; 251 252 BITMAPFILEHEADER bfh; 253 memset(&bfh,0,sizeof(bfh)); 254 bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/; 255 bfh.bfSize= sizeof(bfh)+3*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER); 256 bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER); 257 DWORD dwWritten=0; 258 WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL); 259 BITMAPINFOHEADER bih; 260 memset(&bih,0,sizeof(bih)); 261 bih.biSize=sizeof(bih); 262 bih.biWidth=Bitmap.bmWidth; 263 bih.biHeight=Bitmap.bmHeight; 264 bih.biPlanes=1; 265 bih.biBitCount=24; 266 267 if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL) ) 268 { 269 return FALSE; 270 } 271 272 BITMAPINFO bitmapInfo; 273 memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO) ); 274 bitmapInfo.bmiHeader=bih; 275 276 HDC hMemDC=CreateCompatibleDC(hDC); 277 BYTE *m_lpBitBmp=new BYTE[3*Bitmap.bmWidth*Bitmap.bmHeight]; 278 HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp, 279 NULL,0); 280 if(hDibBitmap != 0) 281 { 282 ::SelectObject(hMemDC,hDibBitmap); 283 BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY); 284 WriteFile(fh,m_lpBitBmp,3*Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL); 285 } 286 287 DeleteObject(hDibBitmap); 288 DeleteDC(hDC); 289 DeleteDC(hMemDC); 290 291 CloseHandle(fh); 292 293 return 1; 294 295 }
1 /*索引颜色/颜色表 2 3 位图常用的一种压缩方法。从位图图片中选择最有代表性的若干种颜色(通常不超过256种)编制成颜色表, 4 然后将图片中原有颜色用颜色表的索引来表示。 5 这样原图片可以被大幅度有损压缩。适合于压缩网页图形等颜色数较少的图形, 6 不适合压缩照片等色彩丰富的图形。 */ 7 8 int Save32BitmapToFile(HBITMAP hBitmap,LPCTSTR lpFileName)//将截屏所得保存为32位带颜色表的图片 9 { 10 /*若不使用颜色表,则去掉bih.biCompression=BI_BITFIELDS;这句,然后 11 不设置bitmapInfo.bmiColors[0].rgbRed=255; 12 bitmapInfo.bmiColors[0].rgbGreen=255; 13 bitmapInfo.bmiColors[0].rgbBlue=255;*/ 14 15 HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); 16 HDC hOffDC=CreateCompatibleDC(hDC); 17 SelectObject(hOffDC,hBitmap); 18 19 BITMAP Bitmap; 20 GetObject(hBitmap,sizeof(BITMAP),&Bitmap); 21 22 HANDLE fh=CreateFile(lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, 23 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); 24 if(fh == INVALID_HANDLE_VALUE ) 25 return FALSE; 26 27 BITMAPFILEHEADER bfh; 28 memset(&bfh,0,sizeof(bfh)); 29 bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/; 30 bfh.bfSize= sizeof(bfh)+4*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER); 31 bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER); 32 33 DWORD dwWritten=0; 34 WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL); 35 BITMAPINFOHEADER bih; 36 memset(&bih,0,sizeof(bih)); 37 bih.biSize=sizeof(bih); 38 bih.biWidth=Bitmap.bmWidth; 39 bih.biHeight=Bitmap.bmHeight; 40 bih.biPlanes=1; 41 bih.biBitCount=32; 42 bih.biCompression=BI_BITFIELDS; 43 44 45 if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL) ) 46 { 47 return FALSE; 48 } 49 50 BITMAPINFO bitmapInfo; 51 memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO) ); 52 bitmapInfo.bmiHeader=bih; 53 bitmapInfo.bmiColors[0].rgbRed=255; 54 bitmapInfo.bmiColors[0].rgbGreen=255; 55 bitmapInfo.bmiColors[0].rgbBlue=255; 56 57 58 HDC hMemDC=CreateCompatibleDC(hDC); 59 BYTE *m_lpBitBmp=new BYTE[4*Bitmap.bmWidth*Bitmap.bmHeight]; 60 HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp, 61 NULL,0); 62 if(hDibBitmap != 0) 63 { 64 ::SelectObject(hMemDC,hDibBitmap); 65 BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY); 66 WriteFile(fh,m_lpBitBmp,4*Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL); 67 } 68 69 DeleteObject(hDibBitmap); 70 DeleteDC(hDC); 71 DeleteDC(hMemDC); 72 73 CloseHandle(fh); 74 75 return 1; 76 77 } 78 79 int SaveJPEGToFile(HBITMAP hBitmap,LPCSTR lpFileName)//将截屏所得保存为jpeg图片 80 { 81 82 83 HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); 84 HDC hOffDC=CreateCompatibleDC(hDC); 85 SelectObject(hOffDC,hBitmap); 86 87 BITMAP Bitmap; 88 GetObject(hBitmap,sizeof(BITMAP),&Bitmap); 89 90 HANDLE fh=CreateFile((LPCWSTR)lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, 91 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); 92 if(fh == INVALID_HANDLE_VALUE ) 93 return FALSE; 94 95 BITMAPFILEHEADER bfh; 96 memset(&bfh,0,sizeof(bfh)); 97 bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/; 98 bfh.bfSize= sizeof(bfh)+3*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER); 99 bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER); 100 DWORD dwWritten=0; 101 // WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL); 102 BITMAPINFOHEADER bih; 103 memset(&bih,0,sizeof(bih)); 104 bih.biSize=sizeof(bih); 105 bih.biWidth=Bitmap.bmWidth; 106 bih.biHeight=Bitmap.bmHeight; 107 bih.biPlanes=1; 108 bih.biBitCount=24; 109 110 /*if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL) ) 111 { 112 return FALSE; 113 }*/ 114 115 BITMAPINFO bitmapInfo; 116 memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO) ); 117 bitmapInfo.bmiHeader=bih; 118 119 HDC hMemDC=CreateCompatibleDC(hDC); 120 BYTE *m_lpBitBmp=new BYTE[bfh.bfSize-sizeof(BITMAPFILEHEADER)]; 121 HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp, 122 NULL,0); 123 if(hDibBitmap != 0) 124 { 125 ::SelectObject(hMemDC,hDibBitmap); 126 BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY); 127 //WriteFile(fh,m_lpBitBmp,bfh.bfSize-sizeof(BITMAPFILEHEADER),&dwWritten,NULL); 128 WriteJPEGFile(lpFileName, m_lpBitBmp,Bitmap.bmWidth,Bitmap.bmHeight,TRUE, 60); 129 130 } 131 132 DeleteObject(hDibBitmap); 133 DeleteDC(hDC); 134 DeleteDC(hMemDC); 135 136 CloseHandle(fh); 137 138 return 1; 139 140 } 141 142 143 // 144 // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) 145 // 146 // 目的: 处理主窗口的消息。 147 // 148 // WM_COMMAND - 处理应用程序菜单 149 // WM_PAINT - 绘制主窗口 150 // WM_DESTROY - 发送退出消息并返回 151 // 152 // 153 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 154 { 155 int wmId, wmEvent; 156 PAINTSTRUCT ps; 157 HDC hdc; 158 159 static SHACTIVATEINFO s_sai; 160 int iWidth,iHeight; 161 HBITMAP hBitmap; 162 163 static int s_cxBegin; 164 static int s_cyBegin; 165 static int s_cxEnd; 166 static int s_cyEnd; 167 switch (message) 168 { 169 case WM_COMMAND: 170 wmId = LOWORD(wParam); 171 wmEvent = HIWORD(wParam); 172 // 分析菜单选择: 173 switch (wmId) 174 { 175 case IDM_HELP_ABOUT: 176 DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About); 177 break; 178 case IDM_OK: 179 SendMessage (hWnd, WM_CLOSE, 0, 0); 180 break; 181 182 case ID_RGB16: 183 184 hBitmap=CopyScreenToBitmap(iWidth,iHeight); 185 Save16BitmapToFile(hBitmap,TEXT("//a.bmp")); 186 break; 187 188 case ID_RGB24: 189 190 hBitmap=CopyScreenToBitmap(iWidth,iHeight); 191 Save24BitmapToFile(hBitmap,TEXT("//b.bmp")); 192 break; 193 194 case ID_RGB32: 195 hBitmap=CopyScreenToBitmap(iWidth,iHeight); 196 Save32BitmapToFile(hBitmap,TEXT("//c.bmp")); 197 break; 198 199 case ID_JPEG: 200 hBitmap=CopyScreenToBitmap(iWidth,iHeight); 201 SaveJPEGToFile(hBitmap,"d.jpg"); 202 break; 203 204 default: 205 return DefWindowProc(hWnd, message, wParam, lParam); 206 } 207 break; 208 case WM_CREATE: 209 SHMENUBARINFO mbi; 210 211 memset(&mbi, 0, sizeof(SHMENUBARINFO)); 212 mbi.cbSize = sizeof(SHMENUBARINFO); 213 mbi.hwndParent = hWnd; 214 mbi.nToolBarId = IDR_MENU; 215 mbi.hInstRes = g_hInst; 216 217 if (!SHCreateMenuBar(&mbi)) 218 { 219 g_hWndMenuBar = NULL; 220 } 221 else 222 { 223 g_hWndMenuBar = mbi.hwndMB; 224 } 225 226 // 初始化外壳程序激活信息结构 227 memset(&s_sai, 0, sizeof (s_sai)); 228 s_sai.cbSize = sizeof (s_sai); 229 break; 230 231 case WM_LBUTTONDOWN: 232 HCURSOR hCursor; 233 hCursor=SetCursor( LoadCursor(NULL,MAKEINTRESOURCE(IDC_WAIT) ) ); 234 235 s_cxBegin=LOWORD(lParam); 236 s_cyBegin=HIWORD(lParam); 237 238 break; 239 240 241 242 case WM_LBUTTONUP: 243 244 s_cxEnd=LOWORD(lParam); 245 s_cyEnd=HIWORD(lParam); 246 SetCursor( LoadCursor( GetModuleHandle(NULL),MAKEINTRESOURCE(IDC_ARROW) ) ); 247 248 break; 249 case WM_PAINT: 250 hdc = BeginPaint(hWnd, &ps); 251 252 // TODO: 在此添加任意绘图代码... 253 254 EndPaint(hWnd, &ps); 255 break; 256 case WM_DESTROY: 257 CommandBar_Destroy(g_hWndMenuBar); 258 PostQuitMessage(0); 259 break; 260 261 case WM_ACTIVATE: 262 // 向外壳程序通知我们的激活消息 263 SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE); 264 break; 265 case WM_SETTINGCHANGE: 266 SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); 267 break; 268 269 default: 270 return DefWindowProc(hWnd, message, wParam, lParam); 271 } 272 return 0; 273 }