none
关于内存设备,CreateCompatibleDC的用法 RRS feed

  • 问题

  • /*---------------------------------------------------------------------------  
    BITMASK.C -- Bitmap Masking Demonstration  
    (c) Charles Petzold, 1998  
    ----------------------------------------------------------------------------*/   
    #include <windows.h>  
    LRESULT CALLBACK  WndProc (HWND, UINT, WPARAM , LPARAM) ;  
    int WINAPI  WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance ,  
                        PSTR szCmdLine, int iCmdShow )  
    {  
      static TCHAR szAppName [] = TEXT ("BitMask") ;  
      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_APPLICATION ) ;  
      wndclass .hCursor =  LoadCursor  (NULL, IDC_ARROW) ;  
      wndclass .hbrBackground  = (HBRUSH ) GetStockObject (LTGRAY_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 ("Bitmap Masking Demo" ),  
        WS_OVERLAPPEDWINDOW,  
        CW_USEDEFAULT , CW_USEDEFAULT ,  
        CW_USEDEFAULT , CW_USEDEFAULT ,  
        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)  
    //Defoe.Tu  tyysoft@yahoo.com.cn Windows 程序设计 PDF 美化版 
    {  
      static HBITMAP hBitmapImag, hBitmapMask  ;  
      static HINSTANCE hInstance ;  
      static int  cxClient , cyClient , cxBitmap , cyBitmap  ;  
      BITMAP bitmap  ;  
      HDC  hdc , hdcMemImag, hdcMemMask  ;  
      int x, y ;  
      PAINTSTRUCT ps ;  
       
      switch ( message)  
      {  
      case  WM_CREATE:  
        hInstance = ((LPCREATESTRUCT) lParam)-> hInstance ;  
        // Load the original image and get its size  
        hBitmapImag  =  LoadBitmap  (hInstance, TEXT ("Matthew")) ;  
        GetObject (hBitmapImag, sizeof (BITMAP), & bitmap) ;  
        cxBitmap  =  bitmap .bmWidth ;  
        cyBitmap  =  bitmap .bmHeight  ;  
         
        // Select the original image into a memory DC  
        hdcMemImag  =  CreateCompatibleDC  (NULL) ;  
        SelectObject (hdcMemImag , hBitmapImag ) ;  
        // Create the monochrome mask bitmap and memory DC  
        hBitmapMask  =  CreateBitmap (cxBitmap , cyBitmap , 1, 1,  NULL) ;  
        hdcMemMask  =  CreateCompatibleDC  (NULL) ;  
        SelectObject (hdcMemMask , hBitmapMask ) ;  
         
        // Color the mask bitmap black with a white ellipse  
        SelectObject (hdcMemMask , GetStockObject (BLACK_BRUSH )) ;  
        Rectangle (hdcMemMask , 0, 0,  cxBitmap , cyBitmap ) ;  
        SelectObject (hdcMemMask , GetStockObject (WHITE_BRUSH )) ;  
        Ellipse (hdcMemMask, 0, 0,  cxBitmap , cyBitmap ) ;  
         
        // Mask the original image  
        BitBlt  (hdcMemImag, 0, 0,  cxBitmap , cyBitmap ,  
          hdcMemMask, 0, 0,  SRCAND) ;  
        DeleteDC  (hdcMemImag ) ;  
        DeleteDC  (hdcMemMask ) ;  
        return 0 ;  
         
      case  WM_SIZE:  
        cxClient  =  LOWORD  (lParam ) ;  
        cyClient  =  HIWORD  (lParam ) ;  
        return 0 ;  
         
      case  WM_PAINT :  
        hdc  =  BeginPaint (hwnd, & ps) ;  
         
        // Select bitmaps into memory DCs  
         
        hdcMemImag  =  CreateCompatibleDC  (hdc ) ;  
        SelectObject (hdcMemImag , hBitmapImag ) ;  
         
        hdcMemMask  =  CreateCompatibleDC  (hdc ) ;  
        SelectObject (hdcMemMask , hBitmapMask ) ;  
         
        // Center image  
         
        x = (cxClient  -  cxBitmap ) / 2 ;  
        y = (cyClient  -  cyBitmap ) / 2 ;  
         
        // Do the bitblts   
         
        BitBlt  (hdc , x, y, cxBitmap , cyBitmap , hdcMemMask , 0, 0, 0x220326) ;  
        BitBlt  (hdc , x, y, cxBitmap , cyBitmap , hdcMemImag , 0, 0,  SRCPAINT ) ;  
         
        DeleteDC  (hdcMemImag ) ;  
        DeleteDC  (hdcMemMask ) ;  
        EndPaint  (hwnd, & ps) ;  
        return 0 ;  
         
      case  WM_DESTROY:  
        DeleteObject (hBitmapImag ) ;  
        DeleteObject (hBitmapMask ) ;  
        PostQuitMessage (0) ;  
        return 0 ;  
      }  
      return DefWindowProc  (hwnd, message, wParam , lParam ) ;  
    }
    

    ------------------------------------------------------------------------------------------------------
    请问

     

     // Select the original image into a memory DC  
        hdcMemImag  =  CreateCompatibleDC  (NULL) ;  
        SelectObject (hdcMemImag , hBitmapImag ) ;  
        // Create the monochrome mask bitmap and memory DC  
        hBitmapMask  =  CreateBitmap (cxBitmap , cyBitmap , 1, 1,  NULL) ;  
        hdcMemMask  =  CreateCompatibleDC  (NULL) ;  
        SelectObject (hdcMemMask , hBitmapMask ) ; 
    

    -----------------------------------------------------------------------------------------------------------------------


    能不能改成

     

     // Select the original image into a memory DC  
        hdc = GetDC (hwnd) ;
    
        hdcMemImag  =  CreateCompatibleDC  (hdc) ;  
        SelectObject (hdcMemImag , hBitmapImag ) ;  
        // Create the monochrome mask bitmap and memory DC  
        hBitmapMask  =  CreateBitmap (cxBitmap , cyBitmap , 1, 1,  NULL) ;  
        hdcMemMask  =  CreateCompatibleDC  (hdc) ;  
        SelectObject (hdcMemMask , hBitmapMask ) ;
    
        ReleaseDC (hwnd, hdc)  ;
    
    ------------------------------------------------------------------------------------------------------
    这两种写法什么区别?

     



    2011年11月26日 7:32

答案

  • 你好,

     

    如果CreateCompatibleDC函数的参数为NULL,那函数所指向的句柄将会是程序当前显示的句柄。 这样做会造成的问题是,如果调用CreateCompatibleDC的线程被销毁,那么CreateCompatibleDC所关联的显示句柄也将被销毁。如果其他线程也不可使用这个句柄。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    • 已标记为答案 Frank.crc 2011年12月13日 5:32
    2011年11月28日 2:54

全部回复

  • 一样的

    看CreateCompatibleDC的说明

    http://baike.baidu.com/view/1080519.htm

    指定为NULL的时候函数自动匹配你应用程序相关的DC


    新浪微博http://weibo.com/xianglitian,欢迎围观
    2011年11月28日 2:37
  • 你好,

     

    如果CreateCompatibleDC函数的参数为NULL,那函数所指向的句柄将会是程序当前显示的句柄。 这样做会造成的问题是,如果调用CreateCompatibleDC的线程被销毁,那么CreateCompatibleDC所关联的显示句柄也将被销毁。如果其他线程也不可使用这个句柄。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    • 已标记为答案 Frank.crc 2011年12月13日 5:32
    2011年11月28日 2:54
  • 你好,

     

    如果CreateCompatibleDC函数的参数为NULL,那函数所指向的句柄将会是程序当前显示的句柄。 这样做会造成的问题是,如果调用CreateCompatibleDC的线程被销毁,那么CreateCompatibleDC所关联的显示句柄也将被销毁。如果其他线程也不可使用这个句柄。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us

    为什么我觉得你说的是错的。

    CreateCompatibleDC创建出来的DC只是和传入的DC属性一样,而没有任何关联的。
    而且: CreateCompatibleDC(NULL) ==
              CreateCompatibleDC(GetDC(NULL)) ==
              CreateCompatibleDC(GetDC(GetDesktopWindow()))

    2011年11月28日 5:51
  • 我查过msdn,我也编译器编译过。两者看着效果一样,就是不知道在处理其他问题是会不会存在问题。
    2011年11月28日 12:51
  • 你好,

     

    如果CreateCompatibleDC函数的参数为NULL,那函数所指向的句柄将会是程序当前显示的句柄。 这样做会造成的问题是,如果调用CreateCompatibleDC的线程被销毁,那么CreateCompatibleDC所关联的显示句柄也将被销毁。如果其他线程也不可使用这个句柄。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    那CreateCompatibleDC不应该是关联着当前显示的一个窗口吗,难道还有多个?
    2011年11月28日 13:04
  • 是有差别的,在CompatibleDC刚一创立的时候像素是1*1黑白的,如果你放hdc作为参数的话,它的调色板默认就和hdc一样了。

    需要考虑程序上下环境。如果我没记错的话,传NULL的SetObject放图片进去,再打印这个DC打印出的是黑白的,传hdc比如DesktopDC的打印的就和桌面的颜色是一样的

    不过你最好写个小程序验证下,很久没用记不得了

     


    0xBAADF00D
    2011年11月29日 2:59
    版主
  • 你好,

     

    如果CreateCompatibleDC函数的参数为NULL,那函数所指向的句柄将会是程序当前显示的句柄。 这样做会造成的问题是,如果调用CreateCompatibleDC的线程被销毁,那么CreateCompatibleDC所关联的显示句柄也将被销毁。如果其他线程也不可使用这个句柄。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    那CreateCompatibleDC不应该是关联着当前显示的一个窗口吗,难道还有多个?
    和窗口无关,这个相当于在内存中开了一块绘图区域,可以想象成内存中的一个显示器
    0xBAADF00D
    2011年11月29日 3:01
    版主
  • 是有差别的,在CompatibleDC刚一创立的时候像素是1*1黑白的,如果你放hdc作为参数的话,它的调色板默认就和hdc一样了。

    需要考虑程序上下环境。如果我没记错的话,传NULL的SetObject放图片进去,再打印这个DC打印出的是黑白的,传hdc比如DesktopDC的打印的就和桌面的颜色是一样的

    不过你最好写个小程序验证下,很久没用记不得了

     


    0xBAADF00D

    hdc = BeginPaint (hwnd, &ps) ;
    hdcMem = CreateCompatibleDC (NULL) ;
    hBitmap = LoadBitmap (GetWindowLong (hwnd, GWL_HINSTANCE), TEXT ("bm1")) ; GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; SelectObject (hdcMem, hBitmap) ; BitBlt (hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY) ; DeleteDC (hdcMem) ; EndPaint (hwnd, &ps) ;

    -----------------------------------------------------------------------------

    我测试了这个代码,hBitmap是一张位图,但是打出来是彩色的呀

     



    2011年11月29日 8:15