win32 7 5 區域和路徑

2021-09-24 02:23:58 字數 2600 閱讀 7743

前言:

如果勇敢photoshop繪圖軟體,就一定記得它有「選擇區域」,以及「路徑」的概念,區域用來選定乙個範圍,以便對指定的範圍進行某種操作;而路徑相當於用虛擬的線條進行 「圈地運動」,雖然路徑圈出來的看上去也是乙個區域,但路徑記錄的是「圈地」用的線條而不是圈出來的地。

使用區域:

建立區域:

gdi 中可以用下列區域建立函式來建立區域:

createrectrgn 函式的引數指定了 左上和右下兩個對角的座標。

createellipticrgn 的引數指定了乙個矩形,產生的矩形區域是相切的。

createrllipiticrgnindrect 函式同樣建立橢圓區域,但指定與橢圓相切的矩形是由乙個 rect 結構定義的。

createpolygonrgn 建立乙個多邊形區域。lppoint 指向了一系列的 point 結構, icount 指定了點的數量,ipolyfillmode引數就是 setpolyfillmode 函式使用的引數:alternate 或 winding,結果的不同之處相當於表 7.4中 polygon 函式的兩種區別

如果建立區域成功的話,這些函式返回乙個區域控制代碼 hrgn,區域和畫筆,畫刷等一樣的,都是gdi物件。如果不再使用乙個區域,需要用 deleteobject將它刪除。

合併區域

僅僅上面的函式可能用途不是很大,但是將不同形狀的區域按照各種方式合併在一起,用處就大了,可以因此定義出很複雜的區域。

要合併區域可以使用函式:

合併的方式:dwcombine 指定了合併的方式,它可以是以下取值

區域的用途:

區域主要可以用在兩個地方:建立特殊形狀的視窗和對繪畫區域進行裁剪。

建立特殊視窗圖形:

使用setwindowrgn 函式可以使視窗的形狀由區域指定,如bmpclock 時鐘程式是橢圓形的,當把時鐘移動到其他視窗上面的時候,它的四角並不覆蓋住下層視窗,這就是因為程式中有下面**:

由於 windows對使用的區域儲存乙個拷貝,所以程式在呼叫 setwindowrgn 函式後就可以用 deleteobject 刪掉,並不需要退出時再刪除掉。

另外,區域可以用來對繪畫區域進行裁剪,任意使用以下兩條語句之一:

那麼以後在 hdc上繪製函式的話,只有 hrgn 指定的區域中的點才會被繪畫,對裁剪區區域外的繪畫將會被忽略。同樣,windows 會對選入dc的區域建立乙個拷貝,如果以後不需要這個區域了,那麼在函式執行後,可以馬上用 deleteobject函式將其刪除掉。

使用路徑

建立路徑

路徑不是gdi物件,它並沒有乙個控制代碼,windows對每個dc在內部儲存乙個路徑,每次新開始建立乙個路徑,原有的路徑就會被破壞掉。如果要建立乙個陸行,可以使用 beginpath函式:

呼叫了這個函式以後,對 hdc 使用畫線函式所畫的線條都被會當做路徑記錄,使用畫線函式畫出來的線條可能是不連續的,比如多次呼叫的 lineto函式,最後一點和開始一點不同,這時需要使用 closefigure 函式將路徑封閉起來:

closefigure 函式從 最後一點到第乙個點畫一條直線把路徑封閉起來。windows允許建立多個子路徑,封閉前面一條路徑以後,可以繼續「圈」出和前面路徑不相連的另一條路徑。

最後,使用 endpath 函式結束建立路徑:

舉例:如圖,示範了一次建立路徑的過程,在第1步調用beginpath 和 第11步調用 endpath之間,用 lineto 函式和 rectangle 畫出了包含兩個三角形和乙個矩形區域,其中兩個三角形用 closefigure去封閉:

使用路徑:

建立了路徑以後,我們可以進行下面操作:

首先,對路徑進行畫線操作,或者對路徑圍起來的區域進行填充操作:

第乙個函式沿著路徑用當前畫筆描繪線條。

第二個函式使用當前畫刷填充路徑圍起來的區域。

第三個函式既使用當前畫筆繪畫邊線也使用當前畫刷填充中間區域。

說明:當執行了任何乙個函式的時候,路徑都會被破壞掉。實際上,這些函式的功能就相當於 7.2.3節中的畫線和填充函式,那麼為什麼要這樣大動干戈呢?唯一的好處就是用這種方法可以操作很複雜的形狀,因為定義路徑時可以使用任何畫線函式,包括畫弧與畫貝塞爾曲線函式等,而用普通的填充函式是無法填充出乙個由貝塞爾曲線圍成的區域的。

路徑的另乙個用途是定義乙個複雜形狀的區域,可以使用下面的函式將路徑轉換為區域:

這個可以用來定義形狀複雜的多的區域。同樣,執行了pathtoregion函式以後,原有的路徑定義就會被破壞掉。

LeetCode 307 區域和檢索

給定乙個整數陣列 nums,求出陣列從索引 i 到 j i j 範圍內元素的總和,包含 i,j 兩點。update i,val 函式可以通過將下標為 i 的數值更新為 val,從而對數列進行修改。利用樹狀陣列實現。from typing import class numarray def init ...

303 區域和檢索 陣列不可變

給定乙個整數陣列 nums,求出陣列從索引 i 到 j i j 範圍內元素的總和,包含 i,j 兩點。示例 給定 nums 2,0,3,5,2,1 求和函式為 sumrange sumrange 0,2 1 sumrange 2,5 1 sumrange 0,5 3 說明 你可以假設陣列不可變。會多...

303 區域和檢索 陣列不可變

給定乙個整數陣列 nums,求出陣列從索引 i 到 j i j 範圍內元素的總和,包含 i,j 兩點。示例 給定 nums 2,0,3,5,2,1 求和函式為 sumrange sumrange 0,2 1 sumrange 2,5 1 sumrange 0,5 3說明 你可以假設陣列不可變。會多次...