投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/6/7 12:28:36
>> あるいは CreateDC で "DISPLAY" のコンテキストを得るようにします。
> CreateDC で "DISPLAY" のコンテキストは、なぜかエラーになってしまい、

ごめんなさい、先のサンプル色々間違いだらけですね。寝ぼけてたかな…。

正しくはこうです。32bit 版の Excel 2016 で動作することを確認済み。

Option Explicit

#If VBA7 Then
Private Declare PtrSafe Function CreateDCW Lib "gdi32" (ByVal pwszDriver As LongPtr, ByVal pwszDevice As LongPtr, ByVal pszPort As LongPtr, ByVal pdm As LongPtr) As LongPtr
Private Declare PtrSafe Function DeleteDC Lib "gdi32" (ByVal hDC As LongPtr) As Long
Private Declare PtrSafe Function GetPixel Lib "gdi32" (ByVal hDC As LongPtr, ByVal nXPos As LongByVal nYPos As LongAs OLE_COLOR
#Else
Private Declare Function CreateDCW Lib "gdi32" (ByVal pwszDriver As OLE_HANDLE, ByVal pwszDevice As OLE_HANDLE, ByVal pszPort As OLE_HANDLE, ByVal pdm As OLE_HANDLE) As OLE_HANDLE
Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As OLE_HANDLE) As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As OLE_HANDLE, ByVal nXPos As LongByVal nYPos As LongAs OLE_COLOR
#End If

Public Function GetColor(ByVal x As LongByVal y As LongAs OLE_COLOR
#If VBA7 Then
    Dim hDC As LongPtr, NullPtr As LongPtr
#Else
    Dim hDC As OLE_HANDLE, NullPtr As LongPtr
#End If
    NullPtr = 0
    hDC = CreateDCW(StrPtr("DISPLAY"), NullPtr, NullPtr, NullPtr)
    GetColor = GetPixel(hDC, x, y)
    DeleteDC hDC
End Function



> hDC = GetDC(ByVal CLngPtr(0))で、試してみました。
CLngPtr は Office 2010 以降で無いと使えないので、バージョン依存性を減らす場合は
#If ディレクティブの併用が必要ですね。


GetDC( ゼロ ) か CreateDCW("DISPLAY",...) に頼らない場合は、
下記の正攻法のルートになるのでしょうけれども、
これを VBA から呼び出すのはなかなかキツそうです。
https://qiita.com/eguo/items/90604787a6098af404d9


> 無事、色を取得できたようですが、
> なぜか、RGBが逆さな気がしました。
> 先ほどの色が逆さの謎が解けました。
混乱させてしまい申し訳ありません。先に訂正した通り、
GetPixel で得られる COLORREF は 0x00bbggrr の順です。
https://docs.microsoft.com/ja-jp/windows/win32/gdi/colorref

純赤の場合、HTML や CSS の世界だと #FF0000 で表現されますが、
VBA の vbRed や RGB(255, 0, 0) だと 0000FF になります。
GetPixel API も同様に 0000FF で返します。

純青の場合、HTML や CSS の世界だと #0000FF で表現されますが
VBA の vbBlue や RGB(0, 0, 255) だと FF0000 になります。
GetPixel API も同様に FF0000 で返します。

GDI+ の Bitmap.GetPixel メソッド(GdipBitmapGetPixel API)は、
透明度0%(不透明)の純赤なら FFFF0000、透明度75% なら 40FF0000
透明度0%(不透明)の純青なら FF0000FF、透明度75% なら 400000FF です。

Option Explicit

Private Type COLORREF
    R As Byte
    G As Byte
    B As Byte
    'Reserved As Byte 
End Type

Private Type DWORD
    Value As Long
End Type

Private Sub ColorTest()
    Dim c As COLORREF
    Dim d As DWORD

    d.Value = vbRed
    LSet c = d
    Debug.Print Hex(d.Value) 'FF 
    Debug.Print Hex(c.R), Hex(c.G), Hex(c.B) 'FF 0 0 

    d.Value = vbBlue
    LSet c = d
    Debug.Print Hex(d.Value) 'FF0000 
    Debug.Print Hex(c.R), Hex(c.G), Hex(c.B) '0 0 FF 

    d.Value = &HEDA96521
    LSet c = d
    Debug.Print Hex(d.Value) 'EDA96521 
    Debug.Print Hex(c.R), Hex(c.G), Hex(c.B) '21 65 A9 
End Sub