トップ > 備忘録 > デバイスコンテキスト関連

デバイスコンテキスト関連2012.11.23   [更新日]2024.12.30

デバイスコンテキスト(以下DC)とは、ディスプレイやプリンタなどの表示デバイスと、アプリケーションの仲介を行うWindowsの仕組みです。Windowsアプリケーションは、特定のデバイスを意識しなくとも、このDCに対して描画を行なえばよいのです。
VBAでは、Win32APIなどを用いフォームに描写したり、画像を扱う際に使用することがあります。
ここでは、デバイスコンテキストのハンドル取得に関する、サンプルコードとメモを記載します。

このページに記載のコードの対応バージョンはExcel2010以降です。


【お薦め】マクロ・プロシージャを管理する無料のツール!
 Excelマクロ管理ツール

ポイント

・GetDC関数(Win32API)
・ReleaseDC関数(Win32API)
・CreateCompatibleDC関数(Win32API)
・DeleteDC関数(Win32API)

DCのハンドルは取得したら解放、作成したら削除しなければならない。
具体的には GetDC 関数や GetWindowDC 関数の後は ReleaseDC 関数で解放し
CreateCompatibleDC 関数でデバイスコンテキストを作った場合は、これを DeleteDC 関数で削除する。

DC関連の関数の返り値は、関数が成功するとハンドル番号、失敗すると「0」を返す。


サンプルコード

以降はDC関連のWin32API関数のサンプルコードである。
VBAでWin32APIを宣言する場合、「宣言セクション」(各モジュールの最上部)に記述しなければならない。

GetDC・ReleaseDC関数

指定したウィンドウのDCの取得・解放

【宣言】

'《指定ウィンドウのデバイス コンテキスト (DC) のハンドルを取得》
' https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getdc
Declare PtrSafe Function GetDC Lib "user32.dll" ( _
                                    ByVal hWnd As LongPtr) As LongPtr
                          
'《デバイス コンテキスト (DC) を解放》
' https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-releasedc
Declare PtrSafe Function ReleaseDC Lib "user32.dll" ( _
                                    ByVal hWnd As LongPtr, _
                                    ByVal hDC As LongPtr) As Long

[引数]
 ・hWnd:ウィンドウハンドル
 ・hDC:既定のデバイスコンテキストハンドル

[メモ]
GetDC関数の引数に「0」を指定すると、画面(スクリーン)全体のDCハンドルを取得する。
ウィンドウのハンドルを指定した場合、そのウィンドウのクライアント領域のDCハンドルを取得する。

【使用例1】
画面全体のデバイスコンテキストのハンドルを表示

'-----------------------------------------------------
' 画面全体のデバイスコンテキストのハンドルを取得する
'-----------------------------------------------------
Sub getTheEntireScreenDC()
    Dim hdlDC As LongPtr
    '《指定ウィンドウのデバイス コンテキスト (DC) のハンドルを取得》
    ' ・ 引数1:DC を取得するウィンドウのハンドル
    '   戻り値:成功:指定されたウィンドウのクライアント領域の DC へのハンドル
    '           失敗:0
    hdlDC = GetDC(0)    ' 画面全体のDCハンドル取得
    
    ' DC のハンドルを表示
    MsgBox hdlDC
    
    '《デバイス コンテキスト (DC) を解放》
    ' ・ 引数1:DC が解放されるウィンドウのハンドル
    ' ・ 引数2:解放する DC のハンドル
    '   戻り値:DCが解放された場合      :1
    '           DCが解放去れなかった場合:0
    Call ReleaseDC(0, hdlDC)
End Sub


【使用例2】
 次は、ユーザーフォームにスクリーンの一部を描写するサンプル。


ユーザーフォームを挿入し、フォームのモジュールに以下のコードを貼り付ける。
フォームを表示した後フォーム上をクリックすると、画面の左上の四角形がフォームに描写される。

'-------------------------------------
' Win32API
'-------------------------------------
'《アクティブなウィンドウのウィンドウハンドルを取得》
' https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getactivewindow
Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr

'《指定ウィンドウのデバイス コンテキスト (DC) のハンドルを取得》
' https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getdc
Private Declare PtrSafe Function GetDC Lib "user32.dll" ( _
                                    ByVal hWnd As LongPtr) As LongPtr
                          
'《デバイス コンテキスト (DC) を解放》
' https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-releasedc
Private Declare PtrSafe Function ReleaseDC Lib "user32.dll" ( _
                                    ByVal hWnd As LongPtr, _
                                    ByVal hDC As LongPtr) As Long
                                    
'《DCからDCにピクセルの四角形に対応する色データのビットブロックを転送》
' https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/nf-wingdi-bitblt
Private Declare PtrSafe Function BitBlt Lib "gdi32.dll" ( _
                                    ByVal hDestDC As LongPtr, _
                                    ByVal x As Long, _
                                    ByVal y As Long, _
                                    ByVal nWidth As Long, _
                                    ByVal nHeight As Long, _
                                    ByVal hSrcDC As LongPtr, _
                                    ByVal xSrc As Long, _
                                    ByVal ySrc As Long, _
                                    ByVal dwRop As Long) As Long

'-------------------------------------
' 定数
'-------------------------------------
' BitBlt ラスタオペレーション
Private Const SRCCOPY = &HCC0020 'コピー元をそのままコピー先にコピー

Private Sub UserForm_Click() ' 画面全体のDCハンドルを取得 Dim hdlScreenDC As LongPtr hdlScreenDC = GetDC(0) ' フォームのウィンドウハンドル取得 Dim hdlFormWindow As LongPtr hdlFormWindow = GetActiveWindow() ' フォームのDCハンドルを取得 Dim hdlFormDC As LongPtr hdlFormDC = GetDC(hdlFormWindow) '《DCからDCにピクセルの四角形に対応する色データのビットブロックを転送》 ' ・ 引数1:コピー先のDCハンドル ' ・ 引数2:コピー先の四角形の左上隅の x 座標 ' ・ 引数3:コピー先の四角形の左上隅の y 座標 ' ・ 引数4:ソース四角形と変換先の四角形の幅 ' ・ 引数5:ソース四角形と変換先の四角形の高さ ' ・ 引数6:ソース(コピー元)のDCハンドル ' ・ 引数7:ソース四角形の左上隅の x 座標 ' ・ 引数8:ソース四角形の左上隅の y 座標 ' 戻り値:成功:0以外 失敗:0 Call BitBlt(hdlFormDC, 0, 0, 200, 200, hdlScreenDC, 0, 0, SRCCOPY) ' 画面の左上200×200ピクセルをフォームの左上に描写 ' フォームのDCハンドルを解放 Call ReleaseDC(hdlFormWindow, hdlFormDC) ' 画面全体のDCハンドルを解放 Call ReleaseDC(0, hdlScreenDC) End Sub


CreateCompatibleDC・DeleteDC関数

ウィンドウと互換性のあるDCの作成・削除。
ウィンドウのDCを直接使うのではなく、メモリ上にそのウィンドウと互換性のあるDCを作成し使う場合に使用する。

【宣言】

'《指定したデバイスと互換性のあるメモリ デバイス コンテキスト (DC) を作成》
' https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/nf-wingdi-createcompatibledc
Declare PtrSafe Function CreateCompatibleDC Lib "gdi32.dll" ( _
                                    ByVal hDC As LongPtr) As LongPtr
                          
'《指定されたデバイス コンテキスト (DC) を削除》
' https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/nf-wingdi-deletedc
Declare PtrSafe Function DeleteDC Lib "gdi32.dll" ( _
                                    ByVal hDC As LongPtr) As Long

[メモ]
 hDC:既定のデバイスコンテキストハンドル
 メモリデバイスコンテキストは、メモリ内にのみ存在する。
 「0」を指定すると、画面全体と互換性のあるメモリデバイスコンテキストが作成される。
 メモリDCを作成した時点では、その表示はモノクロームで、高さと幅は 1 × 1 ピクセル。
 メモリDCを使って描画操作を行う前に、適切な幅と高さを備えたビットマップをメモリDCで選択しなければならない。


【使用例】

Sub getCreateCompatibleDC()
    Dim hdlDC As LongPtr
    '《指定したデバイスと互換性のあるメモリ デバイス コンテキスト (DC) を作成》
    ' ・ 引数1:既存の DC へのハンドル
    '   戻り値:成功:メモリDCのハンドル
    '           失敗:0
    hdlDC = CreateCompatibleDC(0) ' 画面と互換性のあるDCを作成
    
    ' 作成されたメモリDCのハンドルを表示
    MsgBox hdlDC
    
    '《指定されたデバイス コンテキスト (DC) を削除》
    ' ・ 引数1:削除する DC のハンドル
    '   戻り値:成功:0以外 失敗:0
    Call DeleteDC(hdlDC)
End Sub

これらの関数を利用したコードは次を参照


ページトップへ戻る
Copyright(C) 2009- 坂江 保 All Rights Reserved.