可以正常截图 但是此源码截图后位图的最左边的一列其实应该显示在最右边才对(正常情况) 但是现在确反了一列 其他没影响 希望高手帮帮忙 原图如下::
/*---------------------------------------
   BITBLT.C -- BitBlt Demonstration
               (c) Charles Petzold, 1998
  ---------------------------------------*/#include <windows.h>
#include <STDIO.H>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName [] = TEXT ("BitBlt") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_INFORMATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("BitBlt Demo"), 
                          WS_OVERLAPPEDWINDOW, 
                          600, 200,
                          900, 600,
                          NULL, NULL, hInstance, NULL) ;     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static int  cxClient, cyClient, cxSource, cySource ;
     HDC         hdcClient, hdcWindow, hdc;
     HWND deskh;
 static TCHAR szFileName[MAX_PATH],szTitleName[MAX_PATH];
 HBITMAP hbitmap;
     switch (message)
     {
     case WM_CREATE:  
          return 0 ;
     case WM_SIZE:
          cxClient = LOWORD (lParam) ;
          cyClient = HIWORD (lParam) ;
          return 0 ;
 case WM_LBUTTONDOWN:
 HBITMAP oldbit;
 hdcClient = GetDC(hwnd) ;  
 deskh=GetDesktopWindow();
 hdcWindow = GetDC (NULL);
 hbitmap=CreateCompatibleBitmap(hdcWindow,200,200);
 hdc=CreateCompatibleDC(hdcWindow);
 oldbit=(HBITMAP)SelectObject(hdc,hbitmap);
 BitBlt (hdc, 0, 0, 200, 200,hdcWindow, 0, 0, SRCCOPY) ;
 BitBlt (hdcClient, 0, 0, 200, 200,hdc, 0, 0, SRCCOPY) ;     
 hbitmap=(HBITMAP)SelectObject(hdc,oldbit);   
 DWORD bitsize;
 bitsize=((((200*32)+31)&~31)>>3)*200;
 PVOID pmap;
 pmap=malloc (bitsize);
 ZeroMemory( pmap,bitsize );
 ///填充BITMAPINFO结构/////////////////////////
 BITMAPINFO bminfo;
 BITMAPFILEHEADER bmfileheader;
 ZeroMemory(&bminfo,sizeof(BITMAPINFO));
 bminfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
 bminfo.bmiHeader.biWidth=200;
 bminfo.bmiHeader.biHeight=200;
 bminfo.bmiHeader.biPlanes=1;
 bminfo.bmiHeader.biBitCount=32;
 bminfo.bmiHeader.biCompression=BI_RGB;
 ///添加BITMAPFILEHEADER结构/////////////////
 ZeroMemory(&bmfileheader,sizeof(BITMAPFILEHEADER));
 DWORD nbit,magesize,filesize,dwWritten;
 nbit=sizeof(BITMAPFILEHEADER)+bminfo.bmiHeader.biSize;
 magesize=((((bminfo.bmiHeader.biWidth*bminfo.bmiHeader.biBitCount)+31)&~31)>>3)*bminfo.bmiHeader.biHeight;
 filesize=nbit+magesize;
 bmfileheader.bfType='B'+('M'<<8);
 bmfileheader.bfSize=filesize; 
 bmfileheader.bfOffBits=nbit;
 //////////////////////////
 if (!GetDIBits(hdc,hbitmap,0,bminfo.bmiHeader.biHeight,pmap,&bminfo,DIB_RGB_COLORS))
 MessageBeep(0);
 /*DibFileSaveDlg (hwnd, szFileName,  szTitleName);*/
 HANDLE hbmfile;
 hbmfile=CreateFile("e:\\a.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
 if(hbmfile==INVALID_HANDLE_VALUE)
 {
 MessageBox(0,"位图创建不成功",0,0);
 }
 WriteFile(hbmfile,&bmfileheader,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);
 WriteFile(hbmfile,&bminfo,sizeof(BITMAPINFO),&dwWritten,NULL);
 WriteFile(hbmfile,pmap,magesize,&dwWritten,NULL);
 CloseHandle(hbmfile);
 free(pmap);
 ReleaseDC (hwnd, hdcWindow) ;
 DeleteObject(hbitmap);
  DeleteDC(hdc);
 break;
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

解决方案 »

  1.   

    代码太多,头好晕,给个思路,拖框和  进 HBITMAP 这些可以用GDI方法,保存直接用GDI+,可以省很多代码,而且可以选择多种格式
      

  2.   

    “ 但是现在确反了一列”
     一列? 几个 pixel ?
      

  3.   

    宽度计算过的 是4的倍数没问题,话说回来32位的位图本来就是4个字节一像素,随便怎么截图都应该是4的倍数才对,而且在保存到硬盘之前让屏幕截图变成DIB后调用
    SetDIBitsToDevice显示到窗口都是正常的,一旦保存像素位到硬盘:WriteFile(hbmfile,pmap,magesize,&dwWritten,NULL);在E盘下的保存位图就出上面提到问题
    如果把pamap指针定义为BYTE类型后 在WriteFile里写文件时间将次指针加4个BYTE保存正常 问题消失!
    但是为什么会出现加4个BYTE 我就想不明白了!!!
      

  4.   

    可能 GetDIBits(hdc,hbitmap,0,bminfo.bmiHeader.biHeight,pmap,&bminfo,DIB_RGB_COLORS)
    这句 有问题吧
      

  5.   

    摸索了一天重要弄明白了 问题出在写文件:WriteFile(hbmfile,&bminfo,sizeof(BITMAPINFO),&dwWritten,NULL); 这里的sizeof(BITMAPINFO)大小是44个字节
    其实写信息头的大小只有40字节 多出来4个字节产生了一列的错位!用此处WriteFile(hbmfile,&bminfo,bminfo.bmiHeader.biSize,&dwWritten,NULL);代替才对!