GetDC()

GetDC() function retrieves a handle to a display device context for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the device context.

HDC GetDC(
  HWND hWnd   /* handle to a window */
);

Client area and Non-Client Area

GetWindowDC()

GetWindowDC() function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. A window device context permits painting anywhere in a window, because the origin of the device context is the upper-left corner of the window instead of the client area. GetWindowDC assigns default attributes to the window device context each time it retrieves the device context. Previous attributes are lost.

HDC GetWindowDC(
  HWND hWnd   /* handle of window */
);

GetDC() GetWindowDC() drawing

This is an example using API GetDC() and GetWindowDC() APIs and Window event WE_NCPAINT. We have used GetWindowDC to get the device contect of the non client area and we are drawing a rectangle around the edges of this area. We are using left button mouse click to draw in client area. We are using GetDC() to get the device context of the client area. We are drawing rectangle in blue color in non client area and green color in client area.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hWnd,
                         UINT message, 
                         WPARAM wParam,
                         LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  WNDCLASS wc;
  MSG msg;
  HWND hWnd;
  ZeroMemory(&wc, sizeof(WNDCLASS));

  wc.style           = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc     = (WNDPROC)WndProc;
  wc.hInstance       = hInstance;
  wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
  wc.lpszClassName   = (LPCTSTR)"GetDC-GetWindowDC";


  RegisterClass(&wc);

   hWnd = CreateWindow("GetDC-GetWindowDC",
                      "GetDC() and GetWindowDC()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    DispatchMessage(&msg);
  }
  return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

  HDC hDC;
  RECT rect;
  int dc;
  HBRUSH hB;
  LOGBRUSH lb;

  switch (message) 
  {
    /* On Left mouse click we are drawing using GetDC() */
    case WM_LBUTTONDOWN:
    {

      hDC = GetDC(hWnd);
      dc = SaveDC(hDC);
      GetClientRect(hWnd, &rect);
      SelectObject(hDC, CreatePen(PS_SOLID, 4, RGB(0,255,0)));
      lb.lbColor = 0;
      lb.lbStyle = BS_NULL;
      lb.lbHatch = 0;
      hB = CreateBrushIndirect(&lb);
      SelectObject(hDC, hB);
      Rectangle(hDC, 0, 0, rect.right-rect.left , rect.bottom-rect.top);
      RestoreDC(hDC, dc);
      ReleaseDC(hWnd, hDC);
      break;
    }
    /* Window non client area painting */
    case WM_NCPAINT:
    {
      /* Let Windows draw the title bar etc */
      DefWindowProc(hWnd, message, wParam, lParam);

      lb.lbColor = 0;
      lb.lbStyle = BS_NULL;
      lb.lbHatch = 0;

      hDC = GetWindowDC(hWnd);
      dc = SaveDC(hDC);
      GetWindowRect(hWnd, &rect);
      SelectObject(hDC, CreatePen(PS_SOLID, 4, RGB(0,0,255)));
      hB = CreateBrushIndirect(&lb);
      SelectObject(hDC, hB);
      Rectangle(hDC, 0, 0, rect.right-rect.left , rect.bottom-rect.top);
      RestoreDC(hDC, dc);
      ReleaseDC(hWnd, hDC);
      break;
  }

    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

GetDC GetWindowDC output

Client and Non Client area drawing using GetDC() GetWindowDC()

You may also like to know : #WinMain #WNDCLASS #RegisterClass #CreateWindow #Window Proc #GetMessage & DispatchMessage #WPARAM & LPARAM #DefWindowProc #Device Context #PEN #BRUSH #WM_PAINT #SaveDC RestoreDC #GetDC ReleaseDC #Mouse Events

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#