Win32知識之窗口繪制.窗口第一講


       Win32知識之窗口本質

一丶摘要

  在學習Win32的時候. 很多操作都是窗口進行操作的.那么今天就說一下窗口的本質是什么. 

窗口的本質是不斷繪制.是windows通過消息機制進行繪制的.

我們知道.內存分為高低2G 低2G是給應用程序使用的. 高2G是給操作系統使用的.而我們畫圖形的操作都是操作系統通過底層的 win32k.sys這個驅動來提供的.

進程跟線程管理是通過notokerner.exe這個程序來管理的.但是三環不能使用.所以提供接口給三環. 分別是kerner32.dll 跟user32.dll gdi.dll

那么他們之間的區別是什么.

1.kerner32.dll  管理進程線程跟內存的一個dll

2.user32.dll   窗口管理.圖形界面管理.

3.gdi.dll         自己繪制的的管理.

而我們要認識一下窗口的創建.那么需要了解幾個基礎的只是.

1.設備對象.

2.DC設備上下文.

3.圖形對象.

1.設備對象是什么.

  簡而言之設備對象的意思就是你要畫圖形要往哪里畫. 每一個窗口都有一個窗口句柄.而且是存放在全局窗口句柄表中的. 我們可以獲取一下.使用Spy++獲取.

2.DC設備上下文.

  DC設備上下文其實就是這個窗口有一塊內存是繪制用的. 我們想要往這個窗口繪制.需要先繪制到這個內存中才可以.這塊內存就稱為DC上下文.

3.圖形對象.

  圖形對象就是指畫筆 畫刷 位圖. 等等這些對象.因為我們要往內存中畫的時候.可以畫默認的.但是一般我們想改變一下形式.所以創建圖形對象跟DC相關聯.那么我們繪制就可以使用圖形對象了.

二丶繪制窗口步驟

  繪制窗口免不了使用API.但是使用之前.需要知道我們要操作的步驟.

1.獲取窗口句柄.也就是設備對象.

2.獲取窗口中的DC上下文.可以理解為獲取指定窗口的繪圖的那塊內存.

3.創建圖形對象. 要想繪制.那么首先就需要你自定義的一個繪制的東西才可以.

4.關聯圖形對象跟DC. 只要關聯了.那么繪制的時候自動就使用你的圖形對象了.

5.進行你的繪圖操作. 這里就是你寫的繪圖代碼了.

6.釋放資源. 不管是窗口句柄也好. DC也好.圖形對象也好.都是內核對象.所以我們需要進行釋放.

具體API:

 1.獲取指定窗口句柄.     FindWindowA/FindWindowW

HWND FindWindowA(
  LPCSTR lpClassName,              窗口類名.字符串. 可以用Spy++獲取
  LPCSTR lpWindowName           窗口名稱
);
返回窗口句柄.                          

 2.獲取DC設備上下文.   GetDc()

HDC GetDC(
  HWND hWnd                    傳入設備對象.也就是窗口句柄
);

3.創建圖形對象.

 PS: 創建圖形對象.圖形對象有很多. 有畫筆. 畫刷. 等等.

HPEN CreatePen(
  int      iStyle,                創建筆的風格, 意思就是你的畫筆是實心的 還是虛線 還是其他.
  int      cWidth,              筆的寬度.如果實心的.筆的寬度則自定義設置.如果其他.不能超過1
  COLORREF color            RGB的顏色.  你的畫筆是什么顏色的.是一串16進制可以在線取色
);
返回圖形對象

還有常用的.創建矩形區域.

HRGN CreateRectRgn(
  int x1,
  int y1,                             坐標
  int x2,
  int y2
);

具體使用可以查詢MSDN: https://docs.microsoft.com/zh-cn/windows/desktop/gdi/windows-gdi  代碼使用例子

如果你安裝了MSDN 2001版本.搜索SelectObject可以看到. 圖形對象有很多.並且告訴你相應的API

Bitmap  位圖. 后面是操作的API

Brush     畫刷

字體

矩形

4.關聯DC跟圖形對象.

HGDIOBJ SelectObject(  HDC hdc,          // handle to DC
  HGDIOBJ hgdiobj   // handle to object);

 5.寫你想要繪制的代碼.

這里如果是畫線. 則用 LineTo(Hdc,x,y) 這個API  給定一個DC.給個x y坐標.則可以繪制.

當然如果指定在哪里開始繪制則用MoveToEx指定起始位置.

BOOL MoveToEx(
  HDC     hdc,
  int     x,
  int     y,
  LPPOINT lppt
);

6.釋放資源.

釋放資源很簡單了. 如果是圖形對象.同一使用DeleteObject(對象) 進行刪除.

如果是DC. 如果是創建的Dc.則用DeleteDc(DC對象)來進行刪除.

如果是獲取的DC.則用ReleaseDc(Dc對象) 來進行刪除.

題外話. windows程序中還有一個API.可以獲取DC中默認的圖形對象.

HGDIOBJ GetStockObject(
  int i                                  對象的類型.你想從DC中獲取什么對象類型.
);

圖像類型如果是 DC_BRUSH 則是獲取純色刷.就不用自己創建色刷了.可以通過操作色刷的API進行操作.

COLORREF SetDCBrushColor(
  HDC      hdc,
  COLORREF color                   RGB顏色
);

 

三丶繪制圖形.

1.繪制直線的代碼例子.

 

#include "stdafx.h"
#include <Windows.h>

int main(int argc, char *argv[])
{
    
    //1.獲取窗口句柄
    HWND hwnd = ::FindWindow(NULL, TEXT("計算器"));

    //2.獲取DC.
    HDC hdc = ::GetDC(hwnd);

    //3.創建圖形對象.
    HPEN hPen = CreatePen(PS_SOLID, 10, RGB(0xFF, 0, 0)); //設置為紅色畫筆

    //4.關聯圖形對象跟DC
    HPEN oldPen = (HPEN)::SelectObject(hdc, hPen); //返回舊的畫筆
    
    //5.繪制直線.
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, 600, 100);

    //6.釋放資源.
    ::SelectObject(hdc, oldPen); //首先還原舊畫筆
    DeleteObject(hPen);          //刪除圖形對象.
    ReleaseDC(hwnd,hdc);              //釋放Dc

    system("pause");
    return 0;
}

 

運行之后圖片.注意不要遮擋計算器.

 

 2.繪制矩形.獲取默認畫刷.設置畫刷區域顏色.

 繪制代碼

#include "stdafx.h"
#include <Windows.h>

int main(int argc, char *argv[])
{
    
    //1.獲取窗口句柄
    HWND hwnd = ::FindWindow(NULL, TEXT("計算器"));

    //2.獲取DC.
    HDC hdc = ::GetDC(hwnd);

    //3.創建圖形對象.
    HPEN hPen = CreatePen(PS_SOLID, 10, RGB(0xFF, 0, 0)); //設置為紅色畫筆
    HBRUSH hBru = (HBRUSH)::GetStockObject(DC_BRUSH);
    //4.關聯圖形對象跟DC
    HPEN oldPen = (HPEN)::SelectObject(hdc, hPen); //返回舊的畫筆
    SetDCBrushColor(hdc, RGB(0, 0xFF, 0)); //設置畫刷顏色
    HBRUSH oldBrush = (HBRUSH)::SelectObject(hdc, hBru);
    //5.繪制句柄
    Rectangle(hdc, 0, 0, 100, 100);

    //6.釋放資源.
    ::SelectObject(hdc, oldPen); //首先還原舊畫筆
    DeleteObject(hPen);          //刪除圖形對象.
    ReleaseDC(hwnd,hdc);              //釋放Dc

    system("pause");
    return 0;
}

其中新用到的API就是繪制矩形的API. 

繪制完畢結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM