RestoreDC

RestoreDCは、デバイスコンテキストの状態を復元する。

RestoreDC function | Microsoft Docs

SaveDCで取得した正の整数であるIDを指定すると、そのIDを取得した時の状態に戻せるが、負の整数-nを指定すると、現在からn回前の状態に復元することもできる。

RestoreDC.cppのWM_PAINTで、

-1は直前の状態なので青、 -2は2回前なので緑、 -3は3回前なので赤。

最初は、

最初
最初

黒だが、

3回前の赤
3回前の赤

3回前の赤。

2回前の緑
2回前の緑

2回前の緑。

直前の青
直前の青

直前の青。

と、このように負の数を指定しても復元できている。

Sample/winapi/RestoreDC/RestoreDC/src/RestoreDC at master · bg1bgst333/Sample · GitHub

SaveDC

SaveDCは、デバイスコンテキストの状態を保存する。

SaveDC function | Microsoft Docs

SetTextColorでテキストの色、SelectObjectでペンやブラシなどのGDIオブジェクトとの紐づけなど、デバイスコンテキストの状態は頻繫に変わる。
状態を保存しておけば、切り替えに手間がかからない。

SaveDC.cppのWM_COMMANDで、

メニュー項目、Red、Green、Blue、が選択されるごとに、スタティック変数whichの値を変えて画面更新。
あとはWM_PAINTに任せる。

BeginPaint直後に、SetTextColorで赤、緑、青と変えつつ、そのたびにSaveDCで保存している。
SaveDCの戻り値にIDが返り、それをRestoreDCに渡すと復元できる。
なので、最終的にwhichの値で復元する色を決めている。

最初は黒
最初は黒

最初は黒。

Red
Red

Redを選択すると、

赤になる
赤になる

赤になる。

Green
Green

Greenは、

緑になる
緑になる

緑になる。

Blue
Blue

Blueは、

青になる
青になる

青になる。

本当は、あらかじめWM_CREATEとかでSaveDCしてWM_PAINTはRestoreDCだけだったり、1回目の選択でSetTextColorしてSaveDCし、2回目以降はRestoreDCだけするようにしてみたが、デバイスコンテキストハンドルはWM_PAINTするたびに変わってしまい、SaveDCしてもデバイスコンテキストが違うので、状態がスタックしない。
なので、今回はBeginPaintからEndPaintまでの間でSaveDCを繰り返した。
やってみて、これだとSelectObjectやSetTextColorを繰り返すより手間が減るかというと微妙であると感じた・・・。
まあ、量が多ければ減るとはおもうが・・・。

Sample/winapi/SaveDC/SaveDC/src/SaveDC at master · bg1bgst333/Sample · GitHub

GetClientRect

GetClientRectは、ウィンドウのクライアント領域の矩形情報を取得する。

GetClientRect function | Microsoft Docs

GetWindowRectでは、デスクトップ画面の左上を原点とするスクリーン座標だったが、GetClientRectの場合は、左端、上端は0に固定されていて、実質、右端、下端、の数値がサイズ(幅と高さ)も表している。
さて、WM_SIZEも、リサイズ後のクライアント領域のサイズ(幅と高さ)を表していることは以前扱った。
つまり、この2種類の方法で取得した矩形情報は同じ値になるはずである。

WM_SIZEで、

rcWmSizeには、WM_SIZEで渡されたlParamから幅と高さをセットしている。
rcClientは、GetClientRectで取得している。
そのあと、InvalidateRectで画面更新。

WM_PAINTでは、

WM_SIZEで取得したrcWmSizeは、赤で描画。
GetClientRectで取得したrcClientは、青で描画。

起動時
起動時

起動時、値は一緒。

小さくしても一緒
小さくしても一緒

小さくしても一緒。

再度少し横に広げても一緒
再度少し横に広げても一緒

再度少し横に広げても一緒、全く同じである。

Sample/winapi/GetClientRect/GetClientRect/src/GetClientRect at master · bg1bgst333/Sample · GitHub

GetWindowRect

GetWindowRectは、ウィンドウの矩形情報(位置情報やサイズ)を取得する。

GetWindowRect function | Microsoft Docs

WindowProcのWM_MOVE、WM_SIZEで、

GetWindowRectで、スタティックなRECT構造体rcWndにウィンドウの矩形情報を格納する。
デスクトップ画面の左上を原点とするスクリーン座標で左端、上端、右端、下端、の位置が格納される。
そのあとに、InvalidateRectで画面を更新。

WM_PAINTは、

テキストは赤にして、各メンバを文字列に変換して、TextOutで描画している。
InvalidateRectのたびに呼び出されるので、ウィンドウを動かしたり、ウィンドウをリサイズするたびに値が反映される。

実行直後
実行直後

実行直後にこうだとして、ウィンドウを左上に移動させると、

左上に移動
左上に移動

左上が原点なので、全体的に数値は小さくなる。

右下に拡大
右下に拡大

右下に引っ張って、ウィンドウを大きくすると、leftとtopは変わらないが、rightとbottomは大きくなる。

少し右に移動
少し右に移動

少し右に移動すると、leftとrightが少し増える。

Sample/winapi/GetWindowRect/GetWindowRect/src/GetWindowRect at master · bg1bgst333/Sample · GitHub

SetBkMode

SetBkModeは、テキストの背景モード(背景色を描画するか、背景は透過にするか)を設定する。

SetBkMode function | Microsoft Docs

WindowProcのWM_PAINTで、

背景は青、テキストは赤で、TextOutで(50, 50)の位置に描画した後、SetBkModeでTRANSPARENT(透過)にして、TextOutで(50, 100)の位置に再び描画する。

2つ目のテキストは背景なし
2つ目のテキストは背景なし

1つ目のテキストは背景の青が描画されているが、2つ目のテキストは背景が透過されているので、白いままである。

Sample/winapi/SetBkMode/SetBkMode/src/SetBkMode at master · bg1bgst333/Sample · GitHub

SetBkColor

SetBkColorは、TextOutなどでテキストを描画するときの背景となる部分の色を設定する。

SetBkColor function | Microsoft Docs

WindowProcのWM_PAINTで、

背景色は青をセットする。
テキストの描画色はこれまで通り赤をセット。

背景は青
背景は青

このように背景は青になった。

Sample/winapi/SetBkColor/SetBkColor/src/SetBkColor at master · bg1bgst333/Sample · GitHub

RGB

色の指定に、RGBマクロを使うと、どの色かわかりやすい。

RGB macro | Microsoft Docs

WindowProcのWM_PAINTで、

RGBマクロは、R, G, B, の順に指定する。Rが0xffなのでこれも赤。

赤

赤になっている。

Sample/winapi/RGB/RGB/src/RGB at master · bg1bgst333/Sample · GitHub