[[20201216113444]] 『ツールバーに自作のアイコンを追加したい』(しのみや) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『ツールバーに自作のアイコンを追加したい』(しのみや)

 ツールバーに自作のアイコンを追加しようとしていて、
 以下の記述をxlaで保存し、アドイン化しました。

 Private Sub Workbook_AddinInstall()

    On Error Resume Next

    Application.CommandBars("パレット").Delete

    Dim myBar As CommandBar, myButton As CommandBarButton
    Set myBar = Application.CommandBars.Add(Position:=msoBarTop)
    myBar.Name = "パレット"

    Set myButton = myBar.Controls.Add(Type:=msoControlButton)

    myButton.OnAction = "RGB"
    myButton.Caption = "RGB"
    myButton.FaceId = 59

    myBar.Visible = True

    On Error GoTo 0

 End Sub

 ここでmyButton.FaceId = 59の部分を自分が作成したアイコンに変更しようとしています。
 アイコンは、ビットマップで保存したものです。

 どのようにしたらよいでしょうか。

< 使用 Excel:Excel2010、使用 OS:Windows10 >


http://www016.upp.so-net.ne.jp/cheetah/xlvba/Office/CommandBar/index.html
(tokumei) 2020/12/16(水) 12:12

 ありがとうございます。 myButton.Picture=stdole.StdFunctions.LoadPicture("C:アイコン.bmp")
 このようにしたら、表示はされました。

 ただ、このアドインを人と共有しようと考えておりまして、
 cに置いておけないのです。

 どのようにしたら対応できますでしょうか。

(しのみや) 2020/12/16(水) 13:15


 そのブックのユーザーフォームのイメージコントロールにでも読み込んでおき

 myButton.Picture = UserForm1.Image1.Picture

 とかが簡単でしょうか。
(チオチモリン ) 2020/12/16(水) 14:07


 ありがとうございます
 必要な結果が得られました
 ユーザーフォームに置いてそれを読み込みに行く方法があるのですね
(しのみや) 2020/12/16(水) 15:19

 もうひとつ教えていただきたいことが出てきましたのでよろしくお願いします。

 ツールバーにオプションボタンを置きたくて、

 UserFormにFrameを置いて、オプションボタンを3つ置きました。

 myButton.Picture = UserForm1.Frame1

 このような感じでできるのかな…と試してみているのですが
 どうやら違うようです。

 どのようにしたらよいでしょうか。
(しのみや) 2020/12/18(金) 09:55

 見た目だけの話じゃなくって、
 ちゃんとオプションボタンとして機能するオプションボタンですよね?
 RibbonUIの方でもcheckBoxならありますけど、Optionはどうなんだろ?
 出来るのかな・・・?  私は見たことありません。

 CommandBarのControlは
 ・Button
 ・ComboBox
 ・Popup
 の3種類なので機能としてはComboBoxがいちばん近いと思いますけどね

    Sub Test_Add()
        On Error Resume Next
        Application.CommandBars("パレット").Delete
        On Error GoTo 0

        Dim myBar As CommandBar, myCombo As CommandBarComboBox
        Set myBar = Application.CommandBars.Add(Position:=msoBarTop)
        myBar.Name = "パレット"
        Set myCombo = myBar.Controls.Add(Type:=msoControlComboBox)
        myCombo.Caption = "Combo1"
        myCombo.AddItem "Option1"
        myCombo.AddItem "Option2"
        myCombo.AddItem "Option3"
        myCombo.OnAction = "Combo1_Click"
        myBar.Visible = True
    End Sub
    Sub Combo1_Click()
        MsgBox Application.CommandBars("パレット").Controls("Combo1").ListIndex
    End Sub

(白茶) 2020/12/18(金) 11:40


 >ツールバーにオプションボタンを置きたくて
 UserForm で使用するコントロールは配置できません。 

(MK) 2020/12/18(金) 12:06


 無理矢理ですがFaceIdの切替で「ソレっぽく」見せてみましたので追記しときます

    Sub Test_Add()
        On Error Resume Next
        Application.CommandBars("パレット").Delete
        On Error GoTo 0

        Dim myBar As CommandBar, myCombo As CommandBarComboBox
        Dim myButton As CommandBarButton
        Set myBar = Application.CommandBars.Add(Position:=msoBarTop)
        myBar.Name = "パレット"
        Set myCombo = myBar.Controls.Add(Type:=msoControlComboBox)
        myCombo.Caption = "Combo1"
        myCombo.AddItem "Option1"
        myCombo.AddItem "Option2"
        myCombo.AddItem "Option3"
        myCombo.OnAction = "Combo1_Click"

        Dim i As Long
        For i = 1 To 3
            Set myButton = myBar.Controls.Add(Type:=msoControlButton)
            myButton.Caption = "Button" & i
            myButton.OnAction = "'Button_Click " & i & "'"
            myButton.Style = msoButtonIconAndCaption
            myButton.FaceId = 6083
            If i = 1 Then
                myButton.State = msoButtonDown
                myButton.FaceId = 6082
            End If
        Next
        myBar.Visible = True
    End Sub
    Sub Combo1_Click()
        MsgBox Application.CommandBars("パレット").Controls("Combo1").ListIndex
    End Sub
    Sub Button_Click(id As String)
        With Application.CommandBars("パレット")
            If .Controls("Button" & id).State = msoButtonDown Then Exit Sub
            Dim myButton As CommandBarControl
            For Each myButton In .Controls
                If myButton.Caption Like "Button#" Then
                    myButton.State = msoButtonUp
                    myButton.FaceId = 6083
                End If
            Next
            .Controls("Button" & id).State = msoButtonDown
            .Controls("Button" & id).FaceId = 6082
        End With
    End Sub

(白茶) 2020/12/18(金) 13:14


 ComboBoxを使わさせてもらおうかなと考えていたところ、
 無理やりでも再現されるとは…
 今から動きを勉強させてもらいます!
(しのみや) 2020/12/18(金) 14:57

 FaceIdの切替の頂いた記述をAddinsFileColor0.xlaのThisWorkbookに貼り付けて実行してみたところ、
 ツールバーにコンボボックスとボタンの表示はできました。

 しかし、Button1をクリックするとエラーメッセージが出ます。

  マクロ"\\○○○\Microsoft\Addins\AddinsFileColor0.xla'!'Button_Click 1”を実行できません。
  このブックでマクロが使用できないか、またはすべてのマクロが無効になっている可能性があります。

 なにか私の貼り付け方が悪いのでしょうか…?
(しのみや) 2020/12/18(金) 15:48

 すみませんちょっと進めることができました
(しのみや) 2020/12/18(金) 15:55

 頂いた記述のままですと、
 ボタンの表示が
 ◎Button1 ○Button2 ○Button3となっておりますが、
 ↓
 ◎あああ ○いいい ○ううう としたいので、

 myButton.Caption = "Button" & i
 ここを
 myButton.Caption = "あああ" に変えれば良いと思うのですが
 変えてしまうと

 Sub Button_Click(id As String)
 がうまく動かないのです。

 どのようにしたらよいでしょうか。
(しのみや) 2020/12/18(金) 16:43

 まぁ、いろいろやり様はあると思いますけど
 例えば・・・

    Sub Test_Add()
        On Error Resume Next
        Application.CommandBars("パレット").Delete
        On Error GoTo 0

        Dim myBar As CommandBar
        Dim myButton As CommandBarButton

        Set myBar = Application.CommandBars.Add(Position:=msoBarTop)
        myBar.Name = "パレット"

        Set myButton = myBar.Controls.Add(Type:=msoControlButton)
        myButton.Caption = "あああ"
        myButton.OnAction = "'Button_Click """ & myButton.Caption & """'"
        myButton.Style = msoButtonIconAndCaption
        myButton.FaceId = 6082
        myButton.Tag = "Group1"
        myButton.State = msoButtonDown

        Set myButton = myBar.Controls.Add(Type:=msoControlButton)
        myButton.Caption = "いいい"
        myButton.OnAction = "'Button_Click """ & myButton.Caption & """'"
        myButton.Style = msoButtonIconAndCaption
        myButton.FaceId = 6083
        myButton.Tag = "Group1"

        Set myButton = myBar.Controls.Add(Type:=msoControlButton)
        myButton.Caption = "ううう"
        myButton.OnAction = "'Button_Click """ & myButton.Caption & """'"
        myButton.Style = msoButtonIconAndCaption
        myButton.FaceId = 6083
        myButton.Tag = "Group1"

        myBar.Visible = True
    End Sub
    Sub Button_Click(id As String)
        With Application.CommandBars("パレット")
            If .Controls(id).State = msoButtonDown Then Exit Sub
            Dim myButton As CommandBarControl
            For Each myButton In .Controls
                If myButton.Tag = "Group1" Then
                    myButton.State = msoButtonUp
                    myButton.FaceId = 6083
                End If
            Next
            .Controls(id).State = msoButtonDown
            .Controls(id).FaceId = 6082
        End With
    End Sub

(白茶) 2020/12/18(金) 17:02


 参考出品
 6083 あるんですね。446,1852,3940あたりで諦めてました。
 白茶さん 感謝。
 で、私も作ってみました。

 Sub Test_Bar_Ctrl_Add()
     Dim CB As Office.CommandBar
     Dim i As Long
     On Error Resume Next
     Application.CommandBars(CB_Name).Delete '再作成時
     Set CB = Application.CommandBars(CB_Name)
     On Error GoTo 0
     If CB Is Nothing Then
         Set CB = Application.CommandBars.Add(CB_Name, , , True)
     End If
     '---
     CB.Controls.Add(msoControlButton, 59).OnAction = "TestBtn1"
     Call OP_作成(CB_Name, "Grp1", "○○,◇◇,■■", 1)
     '---
     CB.Controls.Add(msoControlButton, 59).OnAction = "TestBtn2"
     Call OP_作成(CB_Name, "Grp2", "あああ,いいい,ううう", 2)
     CB.Visible = True
 End Sub
 Sub TestBtn1()
     MsgBox OP_Selected(CB_Name, "Grp1")
 End Sub
 Sub TestBtn2()
     MsgBox OP_Selected(CB_Name, "Grp2")
 End Sub
 Sub OP_作成(BarName As String, グループ名 As String, 選択肢 As Variant, Optional 初期値 As Long = 1)
     Dim i As Long
     Dim CB As Office.CommandBar
     Set CB = Application.CommandBars(BarName)
     選択肢 = Split(選択肢, ",")
     For i = 0 To UBound(選択肢)
         With CB.Controls.Add(msoControlButton, 59)
             .Tag = グループ名
             .FaceId = IIf(初期値 = i + 1, 6082, 6083)
             .Caption = 選択肢(i)
             .OnAction = "OP_Click"
             .Style = msoButtonIconAndCaption
         End With
     Next
     CB.Visible = True
 End Sub
 Sub OP_Click()
     Dim CBB As Office.CommandBarButton
     Dim ClickCBB As Office.CommandBarButton
     Set ClickCBB = Application.CommandBars.ActionControl
     For Each CBB In ClickCBB.Parent.Controls
         If CBB.Tag = ClickCBB.Tag Then CBB.FaceId = 6083
     Next
     ClickCBB.FaceId = 6082
 End Sub
 Function OP_Selected(BarName As String, グループ名 As String) As String
     Dim CBB As Office.CommandBarButton
     For Each CBB In Application.CommandBars(BarName).Controls
         If CBB.Tag = グループ名 And CBB.FaceId = 6082 Then OP_Selected = CBB.Caption: Exit For
     Next
 End Function

(チオチモリン ) 2020/12/19(土) 10:17


 忘れてました。
 モジュールの先頭に
 Const CB_Name As String = "TestBar"’任意
 を追加してください。
(チオチモリン ) 2020/12/19(土) 10:33

 ちなみに9631と9632でCheckBoxのオン/オフも表現出来そうですよ。

 手持ちの道具で22714まで並べて眺めてみたんですけど、
 オフ時のイメージは1個ずつしか無さそうでした。

(白茶) 2020/12/21(月) 08:48


 すぐ回答頂いているのに、返信遅くてすみません。
 白茶さんのFaceIdの記述でオプションボタンの必要な動きが得られました。

 こんな風にできるのかな?というのがもう一つ出て来ましたので、よろしくお願いします。

 アドインを2つ追加したとします。

  AddinsFileColor0.xla
   ◎あああ ○いいい ○ううう ←Application.CommandBars("パレット0") 

  AddinsFileColor1.xla
   ■□●○▲△         ←Application.CommandBars("パレット1")

 ◎あああが選択されていて、パレット1の■をクリックしたときに、Aという動作
 ◎あああが選択されていて、パレット1の□をクリックしたときに、Bという動作
 ◎あああが選択されていて、パレット1の●をクリックしたときに、Cという動作
 (省略)
 ◎いいいが選択されていて、パレット1の■をクリックしたときに、Gという動作
 (省略)

 このように、動作を分けたいのです。

 AddinsFileをまたいで?選択されているもののIDを渡すことはできるのだろうか…と考えております…

 もしできなければ、ひとつのAddinsFileする方法にしようかなと考えています。
  AddinsFileColor0.xla
   ◎あああ ○いいい ○ううう ■□●○▲△ ←Application.CommandBars("パレット0")

 しかし、
  AddinsFileColor1.xlaが9まであるので分けておいたほうが管理もしやすいかなと思っています。

 チオチモリン さん
 白茶さんの記述を理解するので今のところ頭の中がいっぱいで… 
 また時間を見つけて勉強をさせて頂きたいと思います。 
 ありがとうございます。
(しのみや) 2020/12/21(月) 11:56

 しのみやさん 
 気が向いたら試してみて下さい。
 選択状態の取得は考慮済みです。

 白茶さん
 CheckBoxのFaceID情報ありがとうございます。
 ついでにチェックボックス版も作ろうかと思いますが、
 チェック状態の戻り値を配列にするかカンマ区切りの文字列にするか 悩みますね。

(チオチモリン ) 2020/12/21(月) 14:50


 実行トリガーはパレット1の各ボタンなので、
 パレット1各ボタンのOnActionに指定したプロシージャの中で、
 パレット0の有無を確認した上で、各オプションボタンのFaceIdを調べて分岐させれば良いのではないでしょうか?
 今回の場合、アドインが分かれているかどうかは、あまり関係ない様に思いますけど・・・。

 >もしできなければ、ひとつのAddinsFileする
 うーん、どうでしょう・・・
 提示頂いているのはあくまで「例」なのでしょうし、
 私も実物を見て言ってる訳じゃないので、あんまり無責任な事は言えないですが、
 今回の場合、パレット1は「パレット0ありき」の様ですから、あえて分ける意味があまり感じられません。

 通常、アドインは「組織」であったり「業務」であったり、ある程度「大きな括り」でひとつにするのが自然ではないかと思います。
 バージョン管理や、配布の問題等、後々の事を考えてなるべく一元的に扱える状態が望ましいのではないかと。

 アドイン1が提供する機能とアドイン2が提供する機能に依存関係があるならば、
 最低でも一方向の依存関係(アドイン2はアドイン1のアペンドである等)しか許容出来ませんしね。
 で、
 もしそこに設計上の意図があるが故の分割なのであれば、
 「もしできなければ」を判断基準にするのは、ちょっと危なっかしくないでしょうか?

 それに関連して、冒頭で気になってはいた事なのですが(すんごい「細かい事」で)、
 Workbook_AddinInstallイベントでパレット作るのも、ちょっと気になります。

 アドイン固有の設定値(例えば各パレットのオプションボタンの初期値等)を指定したい場合、
 アドインファイル自体に保存する事も可能ではありますが、
 Program Files配下にアドインを置くならUACの制限を考慮しないといけないので、
 UserProfile配下にiniファイルを作ったり、レジストリを使って設定値を覚えさせたりします。

 AddinInstallイベントって、そういったアドインの機能「そのもの」ではなく
 機能を構築する為の「下準備」に関する動作に使う為のものだと思うんですよね(文脈的な意味では)
 例えば↓こんな感じの流れです

 Workbook_AddinInstall
 iniファイルの作成、レジストリの登録
 ↓   ----------------------------------------------------------------------------
 Workbook_Open
 ini・レジストリの読み込み → パレットの作成
 ↓                                                    ここが日常的に動かす範囲
 Workbook_BeforeClose
 ini・レジストリの保存 → パレットの削除
 ↓   ----------------------------------------------------------------------------
 Workbook_AddinUninstall
 iniファイル、レジストリの削除

 話が逸れてしまいましたが、
 アドインの分割・統合については、その辺を踏まえてご判断された方が良いと思います。

 ※ あくまでご提示頂いている例を見た限りでの「私見」ですので、あまり真に受けないで下さいね。

(白茶) 2020/12/21(月) 15:19


 白茶さん
 頂いたお話の全部の理解はとてもついていけていない状態ではありますが…

 自分で書きながらもAddinを分けておきたい理由が、
 これといって根拠があるものではないと感じております…

 とても勉強になるお話、ありがとうございます。

 チオチモリン さん
 ただいま頂いた記述を勉強中です。

 また行き詰ると思いますので教えて頂けると助かります。
 ひとまずひとつのAddinで作ってみて違和感がないか…チャレンジしてみます。

(しのみや) 2020/12/21(月) 15:55


横から首を突っ込んですみません
たまたま目にとまって興味深く読ませてもらってました。
白茶さんの手持ちの道具に興味が出てしまい
お伺いしたいのですが、それは一覧表の様なものをお持ちということなのでしょうか
それとも一覧表示や検索が出来る様なマクロを作っておられるのでしょうか
よろしければ詳しく教えて欲しいです

(花村) 2020/12/23(水) 01:51


 手持ちの道具ですか。
 100個ずつ順番に表示させるUserFormです。
 たぶんご想像されてる様な便利なものではありませんよ?
 (検索機能とか無いです。ただ単に並べるだけ)

 一応コード貼っときますね。(しのみやさん、場所お借りします)
 作ったのもかなり前ですし、Excel2010でしか使った事ありませんので、動かなかったら諦めて下さい。

 ShowModalをFalseにしたUserFormに以下のコードを貼って、適当に呼出して下さい。

    Option Explicit
    Rem API宣言=====================================================================================================
    Rem クリップボード関係------------------------------------------------------------------------------------------
    Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long
    Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
    Private Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr
    Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
    Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
    Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
    Rem デバイスコンテキスト関係------------------------------------------------------------------------------------
    Private Declare PtrSafe Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As LongPtr) As LongPtr
    Private Declare PtrSafe Function SelectObject Lib "gdi32" (ByVal hDC As LongPtr, ByVal hObject As LongPtr) As LongPtr
    Private Declare PtrSafe Function DeleteDC Lib "gdi32" (ByVal hDC As LongPtr) As Long
    Private Const CF_BITMAP = 2&
    Rem DIBit関係---------------------------------------------------------------------------------------------------
    Private Declare PtrSafe Function DeleteObject Lib "gdi32" (ByVal hObject As LongPtr) As Long
    Private Type BITMAPINFOHEADER
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
    End Type
    Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
    End Type
    Private Declare PtrSafe Function GetDIBits Lib "gdi32" ( _
        ByVal aHDC As LongPtr, ByVal hBitmap As LongPtr, ByVal nStartScan As Long, ByVal nNumScans As Long, _
        lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Const DIB_RGB_COLORS = 0&
    Private Declare PtrSafe Function SetDIBits Lib "gdi32" ( _
        ByVal hDC As LongPtr, ByVal hBitmap As LongPtr, ByVal nStartScan As Long, ByVal nNumScans As Long, _
        lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare PtrSafe Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
    Private Declare PtrSafe Function CreateDIBSection Lib "gdi32" ( _
        ByVal hDC As LongPtr, pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As LongPtr, _
        ByVal handle As LongPtr, ByVal dw As Long) As LongPtr
    Rem IPicture作成------------------------------------------------------------------------------------------------
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(7) As Byte
    End Type
    Private Type PicBmp
        Size As Long
        Type As Long
        hBmp As Long
        hPal As Long
        Reserved As Long
    End Type
    Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32" (PicDesc As PicBmp, RefIID As GUID, ByVal fPictureOwnsHandle As LongPtr, IPic As IPicture) As Long
    Private Const vbPicTypeBitmap = 1&
    Rem CopyImage---------------------------------------------------------------------------------------------------
    Private Declare PtrSafe Function CopyImage Lib "user32" (ByVal handle As LongPtr, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As LongPtr
    Private Const IMAGE_BITMAP = 0&
    Private Const LR_CREATEDIBSECTION = &H2000&
    Rem その他変数・定数============================================================================================
    Rem ------------------------------------------------------------------------------------------------------------
    Private Const FM_WIDTH As Long = 324
    Private Const FM_HEIGHT As Long = 225
    Rem ------------------------------------------------------------------------------------------------------------
    Private LabelHeader As MSForms.Label
    Private WithEvents ChkCopyFace As MSForms.CheckBox
    Private WithEvents FaceCover As MSForms.Label
    Private LabelIdNum As MSForms.Label
    Private WithEvents PixelCover As MSForms.Label
    Private WithEvents ButtonPrev As MSForms.CommandButton
    Private WithEvents ButtonNext As MSForms.CommandButton
    Private WithEvents ButtonGoto As MSForms.CommandButton
    Private WithEvents ButtonZoom As MSForms.CommandButton
    Private WithEvents ButtonCopy As MSForms.CommandButton
    Private WithEvents ButtonPaint As MSForms.CommandButton
    Private WithEvents ButtonList As MSForms.CommandButton
    Private LabelCap As MSForms.Label
    Private LabelCap2 As MSForms.Label
    Private LabelPx As MSForms.Label
    Rem ------------------------------------------------------------------------------------------------------------
    Private IdZero As Long, IdNow As Long, PicNow As IPictureDisp
    Rem 内部イベント================================================================================================
    Private Sub PrepareControls()
        Dim i As Long
        Me.Width = FM_WIDTH
        Me.Height = FM_HEIGHT
        Set LabelHeader = Me.Controls.Add("Forms.Label.1", "LabelHeader")
        With LabelHeader
            .Top = 2: .Height = 9: .Left = 6: .Width = 180
            .TextAlign = fmTextAlignCenter
        End With
        For i = 0 To 99
            With Me.Controls.Add("Forms.Image.1", "Face" & Format$(i, "000"))
                .Top = 12 + 18 * Int(i / 10): .Height = 18: .Left = 6 + 18 * (i Mod 10): .Width = 18
                .SpecialEffect = fmSpecialEffectRaised
                .BackStyle = fmBackStyleTransparent
            End With
        Next
        Set LabelCap = Me.Controls.Add("Forms.Label.1", "LabelCap")
        With LabelCap
            .Top = 12 + 180 + 1.5: .Height = 9: .Left = 6: .Width = 306
        End With
        Set FaceCover = Me.Controls.Add("Forms.Label.1", "FaceCover")
        With FaceCover
            .Top = 12: .Height = 180: .Left = 6: .Width = 180
            .BackStyle = fmBackStyleTransparent
            .ControlTipText = "拡大画像の描画/右クリックで画像をファイルに保存"
        End With
        Set ButtonPrev = Me.Controls.Add("Forms.CommandButton.1", "ButtonPrev")
        With ButtonPrev
            .Top = 6: .Height = 21: .Left = 190: .Width = 21
            .PicturePosition = fmPicturePositionCenter
            .Picture = CommandBars.GetImageMso("MailMergeGoToPreviousRecord", 16, 16)
            .Accelerator = ","
            .ControlTipText = "前のページ(&<)"
        End With
        Set ButtonNext = Me.Controls.Add("Forms.CommandButton.1", "ButtonNext")
        With ButtonNext
            .Top = 6: .Height = 21: .Left = 211: .Width = 21
            .PicturePosition = fmPicturePositionCenter
            .Picture = CommandBars.GetImageMso("MailMergeGoToNextRecord", 16, 16)
            .Accelerator = "."
            .ControlTipText = "次のページ(&>)"
        End With
        Set ChkCopyFace = Me.Controls.Add("Forms.CheckBox.1", "ChkCopyFace")
        With ChkCopyFace
            .Top = 6: .Height = 21: .Left = 234: .Width = 72
            .Accelerator = "T"
            .Caption = "旧画像(T)"
            .ControlTipText = "CopyFaceを使った古い画像を表示(ちょっと重い)"
        End With
        Set ButtonGoto = Me.Controls.Add("Forms.CommandButton.1", "ButtonGoto")
        With ButtonGoto
            .Top = 6: .Height = 21: .Left = 237 + 54: .Width = 21
            .PicturePosition = fmPicturePositionCenter
            .Picture = CommandBars.GetImageMso("FindDialog", 16, 16)
            .Accelerator = "G"
            .ControlTipText = "指定したIdへジャンプ(&G)"
        End With
        Set ButtonZoom = Me.Controls.Add("Forms.CommandButton.1", "ButtonZoom")
        Set LabelIdNum = Me.Controls.Add("Forms.Label.1", "LabelIdNum")
        With LabelIdNum
            .Top = 30: .Height = 9: .Left = 190: .Width = 7.5 * 16 + 3
        End With
        With Me.Controls.Add("Forms.Frame.1", "Frame2")
            .Top = 39: .Height = 7.5 * 16 + 3: .Left = 190: .Width = 7.5 * 16 + 3
            .SpecialEffect = fmSpecialEffectSunken
            .PictureTiling = True
            Set .Picture = CreateCheckeredPattern(&HE5E5E5, &HFFFFFF, 5)
            For i = 0 To 255
                With .Controls.Add("Forms.Label.1", "Pixel" & Format$(i, "000"))
                    .Top = 7.5 * Int(i / 16): .Height = 7.5: .Left = 7.5 * (i Mod 16): .Width = 7.5
                    .BackStyle = fmBackStyleTransparent
                End With
            Next
            Set PixelCover = .Controls.Add("Forms.Label.1", "PixelCover")
            With PixelCover
                .Height = 7.5 * 16: .Width = 7.5 * 16
                .BackStyle = fmBackStyleTransparent
                .ControlTipText = "透過色の設定/解除"
            End With
        End With
        Set LabelCap2 = Me.Controls.Add("Forms.Label.1", "LabelCap2")
        With LabelCap2
            .Top = 39 + 7.5 * 16 + 3: .Height = 9: .Left = 190: .Width = 7.5 * 16 + 3
        End With
        With ButtonZoom
            .Top = 39 + 7.5 * 16 + 12: .Height = 21: .Left = 190: .Width = 21 '42
            .PicturePosition = fmPicturePositionCenter
            .Picture = CommandBars.GetImageMso("ZoomIn", 16, 16)
            .Accelerator = "Z"
            .ControlTipText = "このフォーム自身を拡大/縮小(&Z)"
        End With
        Set ButtonPaint = Me.Controls.Add("Forms.CommandButton.1", "ButtonPaint")
        With ButtonPaint
            .Top = 39 + 7.5 * 16 + 12: .Height = 21: .Left = 190 + 21.75: .Width = 39
            .Accelerator = "P"
            .Caption = "塗絵(P)"
            .ControlTipText = "選択中の画像でセル塗り絵を作成"
        End With
        Set ButtonList = Me.Controls.Add("Forms.CommandButton.1", "ButtonList")
        With ButtonList
            .Top = 39 + 7.5 * 16 + 12: .Height = 21: .Left = 190 + 21.75 + 39.75: .Width = 39
            .Accelerator = "L"
            .Caption = "書出(L)"
            .ControlTipText = "現在の画像一覧(100個分)を新規シートに書き出し"
        End With
        Set ButtonCopy = Me.Controls.Add("Forms.CommandButton.1", "ButtonCopy")
        With ButtonCopy
            .Top = 39 + 7.5 * 16 + 12: .Height = 21: .Left = 291: .Width = 21
            .PicturePosition = fmPicturePositionCenter
            .Picture = CommandBars.GetImageMso("Copy", 16, 16)
            .Accelerator = "C"
            .ControlTipText = "選択中の画像をクリップボードにコピー(&C)"
        End With
    End Sub

    Private Sub UserForm_Initialize()
        Call PrepareControls
        Call UpdateImageLabels(IdZero)
    End Sub
    Private Sub UserForm_Terminate()
        Set PicNow = Nothing
    End Sub
    Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
        If Not LabelCap Is Nothing Then LabelCap.Caption = Empty
        If Not LabelCap2 Is Nothing Then LabelCap2.Caption = Empty
        If Not LabelPx Is Nothing Then LabelPx.BorderStyle = fmBorderStyleNone
    End Sub
    Private Sub ButtonPrev_Click()
        StartId = StartId - 100
    End Sub
    Private Sub ButtonNext_Click()
        StartId = StartId + 100
    End Sub
    Private Sub ButtonGoto_Click()
        Dim i As Variant
        i = InputBox("番号を入力")
        If IsNumeric(i) Then CurrentId = CLng(i)
    End Sub
    Private Sub ChkCopyFace_Change()
        Call UpdateImageLabels(IdZero, ChkCopyFace.Value)
        Set PicNow = GetImagefromFaceId(IdNow, ChkCopyFace.Value)
        Call UpdatePixelLabels(PicNow.handle)
    End Sub
    Private Sub FaceCover_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
        If x < 0 Or y < 0 Then Exit Sub
        If x > FaceCover.Width Or y > FaceCover.Height Then Exit Sub
        CurrentId = IdZero + Int(y / 18) * 10 + Int(x / 18)
        If PicNow Is Nothing Then Exit Sub
        If Button = 2 Then
            Dim aPath As String, fExist As Boolean
            aPath = Format$(IdNow, "00000") & ".bmp"
            With CreateObject("Scripting.FileSystemObject")
                Do
                    aPath = Application.GetSaveAsFilename(aPath, "ビットマップ,*.bmp,All file,*.*")
                    If aPath = "False" Then Exit Sub
                    fExist = .FileExists(aPath)
                    If fExist Then
                        If MsgBox(.GetFileName(aPath) & " は既に存在します。" & vbCrLf & "上書きしますか?", _
                            vbYesNo + vbExclamation, "上書き保存の確認") = vbYes Then Exit Do
                    End If
                Loop While fExist
            End With
            SavePicture PicNow, aPath
        End If
    End Sub
    Private Sub FaceCover_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
        If x < 0 Or y < 0 Then Exit Sub
        If x > FaceCover.Width Or y > FaceCover.Height Then Exit Sub
        Dim i As Long
        i = Int(y / 18) * 10 + Int(x / 18)
        If i > 99 Then Exit Sub
        LabelCap.Caption = Me.Controls("Face" & Format$(i, "000")).ControlTipText
    End Sub
    Private Sub PixelCover_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
        If x < 0 Or y < 0 Then Exit Sub
        If x > PixelCover.Width Or y > PixelCover.Height Then Exit Sub
        Dim i As Long, bk As fmBackStyle, cl As Long
        With Me.Controls("Pixel" & Format$(Int(y / 7.5) * 16 + Int(x / 7.5), "000"))
            bk = .BackStyle
            bk = IIf(bk = fmBackStyleOpaque, fmBackStyleTransparent, fmBackStyleOpaque)
            cl = .BackColor
        End With
        For i = 0 To 255
            With Me.Controls("Pixel" & Format$(i, "000"))
                .BackStyle = fmBackStyleOpaque
                If .BackColor = cl Then .BackStyle = bk
            End With
        Next
    End Sub
    Private Sub PixelCover_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
        If Not LabelPx Is Nothing Then LabelPx.BorderStyle = fmBorderStyleNone
        If x < 0 Or y < 0 Then Exit Sub
        If x > PixelCover.Width Or y > PixelCover.Height Then Exit Sub
        Dim i As Long
        i = Int(y / 7.5) * 16 + Int(x / 7.5)
        If i > 255 Then Exit Sub
        Set LabelPx = Me.Controls("Pixel" & Format$(i, "000"))
        With LabelPx
            LabelCap2.Caption = .ControlTipText
            .BorderStyle = fmBorderStyleSingle
            .BorderColor = IIf(GetYfromRGB(SysColor2RGB(.BackColor)) < 0.5!, &HFFFFFF, &H0&)
        End With
    End Sub
    Private Sub ButtonCopy_Click()
        If Not PicNow Is Nothing Then
            Dim Pic As IPictureDisp, hBmp As LongPtr
            Set Pic = Me.Controls("Face" & Format$(IdNow - IdZero, "000")).Picture
            Rem Pic.handleをそのままクリップボードに持っていくと、
            Rem IPictureの破棄、あるいは別のビットマップオブジェクトが設定された時点で
            Rem 現ビットマップオブジェクトも破棄されるのでコピーをクリップボードに持っていく
            Rem あとDIBセクションとしてコピーすると貼り付け時に絵が認識できないのでフラグなしでコピー
            hBmp = CopyImage(Pic.handle, IMAGE_BITMAP, 0&, 0&, 0&)
            Call CopyBmptoClipboard(hBmp)
            Call DeleteObject(hBmp)
        End If
    End Sub
    Private Sub ButtonZoom_Click()
        Dim tBarHeight As Single
        tBarHeight = Me.Height - Me.InsideHeight
        If Me.Zoom = 100 Then
            Me.Zoom = 200
            Me.Width = FM_WIDTH * 2
            Me.Height = FM_HEIGHT * 2 - tBarHeight
            ButtonZoom.Picture = CommandBars.GetImageMso("ZoomOut", 16, 16)
        Else
            Me.Zoom = 100
            Me.Width = FM_WIDTH
            Me.Height = FM_HEIGHT
            ButtonZoom.Picture = CommandBars.GetImageMso("ZoomIn", 16, 16)
        End If
    End Sub
    Private Sub ButtonPaint_Click()
        If PicNow Is Nothing Then Exit Sub
        Dim w As Single, c As Range, i As Long
        If ActiveWorkbook Is Nothing Then Workbooks.Add
        If ActiveWorkbook.Path <> "" Or Not ActiveWorkbook.Saved Then Workbooks.Add
        With Cells(1, 1)
            For w = Cells(1, 1).ColumnWidth To 0 Step -0.75
                Cells(1, 1).ColumnWidth = w
                If Cells(1, 1).Width <= Cells(1, 1).Height Then Exit For
            Next
        End With
        Cells(1, 1).Resize(, 17).Columns.ColumnWidth = w
        With Cells(2, 2).Resize(16, 16)
            For Each c In .Cells
                With Me.Controls("Pixel" & Format$(i, "000"))
                    If .BackStyle = fmBackStyleOpaque Then c.Interior.Color = .BackColor
                End With
                i = i + 1
            Next
            With .Borders
                .LineStyle = xlContinuous
                .Weight = xlThin
                .Item(xlInsideHorizontal).LineStyle = xlNone
                .Item(xlInsideVertical).LineStyle = xlNone
            End With
        End With
    End Sub
    Private Sub ButtonList_Click()
        If MsgBox(IdZero & " 〜 " & IdZero + 99 & " までのイメージを出力します", vbInformation + vbOKCancel) = vbCancel Then Exit Sub
        Call CreateFaceImageList(IdZero, IdZero + 99)
    End Sub
    Rem プロパティ==================================================================================================
    Private Property Get CurrentId() As Long
        CurrentId = IdNow
    End Property
    Private Property Let CurrentId(ByVal newId As Long)
        If newId < 0 Then newId = 0
        If IdNow = newId Then Exit Property
        Dim i As Long
        IdNow = newId
        Set PicNow = GetImagefromFaceId(IdNow, ChkCopyFace.Value)
        LabelIdNum.Caption = Format$(IdNow, "00000") & " " & GetControlNamesFromId(IdNow)
        StartId = IdNow
        If PicNow Is Nothing Then
            For i = 0 To 255
                With Me.Controls("Pixel" & Format$(i, "000"))
                    .BackColor = &H80000005
                End With
            Next
        Else
            Call UpdatePixelLabels(PicNow.handle)
        End If
    End Property
    Private Property Get StartId() As Long
        StartId = IdZero
    End Property
    Private Property Let StartId(ByVal newId As Long)
        If newId < 0 Then newId = 0
        newId = Int(newId / 100) * 100
        If IdZero = newId Then Exit Property
        IdZero = newId
        Call UpdateImageLabels(IdZero, ChkCopyFace.Value)
    End Property
    Private Sub UpdateImageLabels(ByVal StartNum As Long, Optional UseCopyFace As Boolean)
        Dim i As Long, Cap As String
        i = StartNum
        For i = 0 To 99
            With Me.Controls("Face" & Format$(i, "000"))
                Set .Picture = GetImagefromFaceId(StartNum + i, UseCopyFace)
                .ControlTipText = "ID:" & Format$(StartNum + i, "00000")
                .SpecialEffect = fmSpecialEffectRaised
                If .Picture Is Nothing Then .SpecialEffect = fmSpecialEffectEtched
                Cap = GetControlNamesFromId(StartNum + i)
                If Len(Cap) > 0 Then
                    .ControlTipText = .ControlTipText & ": " & Cap
                    .SpecialEffect = fmSpecialEffectSunken
                End If
            End With
        Next
        LabelHeader.Caption = StartNum & " to " & StartNum + 99
    End Sub
    Private Sub UpdatePixelLabels(hBmp As LongPtr)
        Dim v() As Variant, i As Long, r As Long, c As Long
        Dim vRGB() As Variant
        v = GetRGBsofBmp(hBmp, 16, 16)
        For r = 1 To 16
            For c = 1 To 16
                With Me.Controls("Pixel" & Format$(i, "000"))
                    .BackColor = v(r, c)
                    vRGB = SplitRGB(CLng(v(r, c)))
                    .ControlTipText = "x=" & c & " y=" & r & " RGB:" & Join(vRGB, ",")
                    .BackStyle = fmBackStyleOpaque
                End With
                i = i + 1
            Next
        Next
    End Sub
    Rem メソッド============================================================================================================
    Public Sub CreateFaceImageList(idFrom As Long, idTo As Long)
        Dim Btn As CommandBarButton, Pic As IPictureDisp, i As Long, r As Long
        Dim hBmp As LongPtr
        Dim ErrNum As Long
        If ActiveWorkbook Is Nothing Then Workbooks.Add
        If ActiveWorkbook.Path <> "" Or Not ActiveWorkbook.Saved Then Workbooks.Add
        [A1:F1] = [{"FaceId",".CopyFace",".Picture",".Mask","MaskedImage",".Caption"}]
        With CommandBars.Add(Name:="test", temporary:=True)
            Set Btn = .Controls.Add(Type:=msoControlButton, temporary:=True)
            r = 2
            For i = idFrom To idTo
                Cells(r, 1) = i
                On Error Resume Next
                Btn.FaceId = i
                ErrNum = Err.Number
                On Error GoTo 0
                If ErrNum = 0 Then
                Rem CopyFace画像
                    Btn.CopyFace
                    Cells(r, 2).Select
                    ActiveSheet.Paste
                Rem 素のPicture画像
                    Set Pic = Btn.Picture
                    Call CopyBmptoClipboard(Pic.handle)
                    Cells(r, 3).Select
                    ActiveSheet.Paste
                Rem Mask画像
                    Set Pic = Btn.Mask
                    Call CopyBmptoClipboard(Pic.handle)
                    Cells(r, 4).Select
                    ActiveSheet.Paste
                Rem マスク適用後のPicture画像
                    hBmp = CopyImage(Btn.Picture.handle, IMAGE_BITMAP, 0&, 0&, 0&)
                    Call SetMask(hBmp, Btn.Mask.handle, 16, 16)
                    Call CopyBmptoClipboard(hBmp)
                    Call DeleteObject(hBmp)
                    Cells(r, 5).Select
                    ActiveSheet.Paste
                Else
                    Cells(r, 2).Value = "(No Image)"
                End If
                Rem コントロールキャプション
                Cells(r, 6).Value = GetControlNamesFromId(i)
                r = r + 1
                DoEvents '画面描画維持
            Next
            Btn.Delete
            .Delete
        End With
    End Sub
    Rem サブルーチン================================================================================================
    Private Function GetControlNamesFromId(ID As Long) As String
        Dim Str As String
        On Error Resume Next
        Str = Application.CommandBars.FindControl(ID:=ID).Caption
        On Error GoTo 0
        GetControlNamesFromId = Str
    End Function
    Private Function GetImagefromFaceId(FaceIdNumber As Long, Optional UseCopyFace As Boolean) As IPictureDisp
        Const BarName As String = "TMP_GetImagefromFaceId"
        On Error Resume Next
        CommandBars(BarName).Delete
        On Error GoTo 0
        Dim Cb As CommandBarButton, hBmp As LongPtr, bkColor As Long, ErrNum As Long
        bkColor = Me.BackColor
        With CommandBars.Add(Name:=BarName, temporary:=True)
            Set Cb = .Controls.Add(Type:=msoControlButton, temporary:=True)
            With Cb
                On Error Resume Next
                .FaceId = FaceIdNumber
                ErrNum = Err.Number
                On Error GoTo 0
                If ErrNum = 0 Then
                    If UseCopyFace Then
                        .CopyFace
                        hBmp = CopyImage(GetBmpfromClipboard, IMAGE_BITMAP, 0&, 0&, LR_CREATEDIBSECTION)
                    Else
                        hBmp = CopyImage(.Picture.handle, IMAGE_BITMAP, 0&, 0&, LR_CREATEDIBSECTION)
                        Call SetMask(hBmp, .Mask.handle, 16, 16, bkColor)
                    End If
                    If hBmp Then Set GetImagefromFaceId = CreatePictureByhBmp(hBmp)
                End If
                .Delete
            End With
            Set Cb = Nothing
            .Delete
        End With
    End Function
    Private Function CopyBmptoClipboard(hBmp As LongPtr) As Boolean
        Call OpenClipboard(0&)
        Call EmptyClipboard
        CopyBmptoClipboard = CBool(SetClipboardData(CF_BITMAP, hBmp))
        Call CloseClipboard
    End Function
    Private Function GetBmpfromClipboard() As LongPtr
        If IsClipboardFormatAvailable(CF_BITMAP) = 0 Then Exit Function
        If OpenClipboard(0&) <> 0 Then
            GetBmpfromClipboard = GetClipboardData(CF_BITMAP)
            Call CloseClipboard
        End If
    End Function
    Private Function CreatePictureByhBmp(ByVal hBmp As LongPtr, Optional hPal As LongPtr) As IPictureDisp
        Dim IID_IDispatch As GUID, Bmp As PicBmp
        With IID_IDispatch
            .Data1 = &H20400
            .Data4(0) = &HC0&
            .Data4(7) = &H46&
        End With
        With Bmp
            .Size = Len(Bmp)
            .Type = vbPicTypeBitmap
            .hBmp = hBmp
            .hPal = hPal
        End With
        Call OleCreatePictureIndirect(Bmp, IID_IDispatch, 1, CreatePictureByhBmp)
    End Function
    Private Function GetRGBsofBmp(ByVal hBmp As LongPtr, pxWidth As Long, pxHeight As Long) As Variant
        Dim Rtn As LongPtr
        Dim bi As BITMAPINFO
        Dim hDC As LongPtr, hOld As LongPtr
        Dim RGBBuff() As Byte, r As Long, c As Long, vRGB() As Variant
        hDC = CreateCompatibleDC(0&)
        hOld = SelectObject(hDC, hBmp)
        With bi.bmiHeader
            .biSize = Len(bi.bmiHeader)
            .biWidth = pxWidth
            .biHeight = -pxHeight 'トップダウン走査
            .biPlanes = 1
            .biBitCount = 32
            .biSizeImage = pxWidth * 4 * pxHeight
        End With
        ReDim RGBBuff(1 To pxWidth * 4, 1 To pxHeight)
        Rtn = GetDIBits(hDC, hBmp, 0&, pxHeight, RGBBuff(1, 1), bi, DIB_RGB_COLORS)
        Call SelectObject(hDC, hOld)
        Call DeleteDC(hDC)
        If Rtn = 0 Then Exit Function
        ReDim vRGB(1 To pxHeight, 1 To pxWidth)
        For r = 1 To pxHeight
            For c = 1 To pxWidth
                vRGB(r, c) = RGBBuff(c * 4 - 1, r) + RGBBuff(c * 4 - 2, r) * &H100& + RGBBuff(c * 4 - 3, r) * &H100& ^ 2
            Next
        Next
        GetRGBsofBmp = vRGB
    End Function
    Private Function SplitRGB(aRGB As Long, Optional Percentage As Boolean) As Variant
        Dim i As Long, Ary(0 To 2) As Variant
        For i = 0 To 2
            Ary(i) = (aRGB \ &H100& ^ i) Mod &H100&
            If Percentage Then Ary(i) = CSng(Ary(i) / &HFF&)
        Next
        SplitRGB = Ary
    End Function
    Private Function SetMask(ByVal hBmp As LongPtr, ByVal hMask As LongPtr, pxWidth As Long, pxHeight As Long, _
        Optional ByVal bkColor As Long = &H8000000F) As Boolean
        Dim Rtn As LongPtr
        Dim bi As BITMAPINFO
        Dim hDC As LongPtr, hOld As LongPtr
        Dim RGBBuff() As Byte, r As Long, c As Long
        Dim MaskBuff() As Byte, bkRGB() As Variant, Alpha(0 To 2) As Single
        hDC = CreateCompatibleDC(0&)
        hOld = SelectObject(hDC, hBmp)
        With bi.bmiHeader
            .biSize = Len(bi.bmiHeader)
            .biWidth = pxWidth
            .biHeight = -pxHeight 'トップダウン走査
            .biPlanes = 1
            .biBitCount = 32
            .biSizeImage = pxWidth * 4 * pxHeight
        End With
        ReDim RGBBuff(1 To pxWidth * 4, 1 To pxHeight)
        ReDim MaskBuff(1 To pxWidth * 4, 1 To pxHeight)
        Rtn = GetDIBits(hDC, hBmp, 0&, pxHeight, RGBBuff(1, 1), bi, DIB_RGB_COLORS)
        Rtn = GetDIBits(hDC, hMask, 0&, pxHeight, MaskBuff(1, 1), bi, DIB_RGB_COLORS)
        bkRGB = SplitRGB(SysColor2RGB(bkColor))
        For r = 1 To pxHeight
            For c = 1 To pxWidth
                Alpha(0) = MaskBuff(c * 4 - 1, r) / &HFF&
                Alpha(1) = MaskBuff(c * 4 - 2, r) / &HFF&
                Alpha(2) = MaskBuff(c * 4 - 3, r) / &HFF&
                RGBBuff(c * 4 - 1, r) = CLng(bkRGB(0) * Alpha(0) + RGBBuff(c * 4 - 1, r) * (1 - Alpha(0))) 'R
                RGBBuff(c * 4 - 2, r) = CLng(bkRGB(1) * Alpha(1) + RGBBuff(c * 4 - 2, r) * (1 - Alpha(1))) 'G
                RGBBuff(c * 4 - 3, r) = CLng(bkRGB(2) * Alpha(2) + RGBBuff(c * 4 - 3, r) * (1 - Alpha(2))) 'B
            Next
        Next
        Rtn = SetDIBits(hDC, hBmp, 0&, pxHeight, RGBBuff(1, 1), bi, DIB_RGB_COLORS)
        Call SelectObject(hDC, hOld)
        Call DeleteDC(hDC)
        If Rtn Then SetMask = True
    End Function
    Private Function SysColor2RGB(SysCol As Long) As Long
        If (SysCol And &HFF000000) = &H80000000 Then
            SysColor2RGB = GetSysColor(SysCol And &HFFFFFF)
        Else
            SysColor2RGB = SysCol
        End If
    End Function
    Function GetYfromRGB(aRGB As Long) As Single
        Const prmR = 0.298912!, prmG = 0.586611!, prmB = 0.114478!
        Dim vRGB() As Variant
        vRGB = SplitRGB(aRGB)
        GetYfromRGB = vRGB(0) * prmR + vRGB(1) * prmG + vRGB(2) * prmB
        GetYfromRGB = GetYfromRGB / &HFF&
        If GetYfromRGB > 1! Then GetYfromRGB = 1!
        If GetYfromRGB < 0! Then GetYfromRGB = 0!
    End Function
    Private Function CreateCheckeredPattern(color1 As Long, color2 As Long, pxSize As Long) As IPictureDisp
        Dim Rtn As LongPtr
        Dim bi As BITMAPINFO
        Dim hDC As LongPtr, hOld As LongPtr, hBmp As LongPtr
        Dim RGBBuff() As Byte, r As Long, c As Long
        Dim RGB1() As Variant, RGB2() As Variant
        With bi.bmiHeader
            .biSize = Len(bi.bmiHeader)
            .biWidth = pxSize * 2
            .biHeight = -pxSize * 2 'トップダウン走査
            .biPlanes = 1
            .biBitCount = 32
            .biSizeImage = (pxSize * 2) * 4 * (pxSize * 2)
        End With
        ReDim RGBBuff(1 To (pxSize * 2) * 4, 1 To (pxSize * 2))
        For r = 1 To (pxSize * 2)
            If r <= pxSize Then
                RGB1 = SplitRGB(color1)
                RGB2 = SplitRGB(color2)
            Else
                RGB1 = SplitRGB(color2)
                RGB2 = SplitRGB(color1)
            End If
            For c = 1 To (pxSize * 2)
                RGBBuff(c * 4 - 1, r) = IIf(c <= pxSize, RGB1(0), RGB2(0)) 'R
                RGBBuff(c * 4 - 2, r) = IIf(c <= pxSize, RGB1(1), RGB2(1)) 'G
                RGBBuff(c * 4 - 3, r) = IIf(c <= pxSize, RGB1(2), RGB2(2)) 'B
            Next
        Next
        hDC = CreateCompatibleDC(0&)
        hBmp = CreateDIBSection(hDC, bi, DIB_RGB_COLORS, 0&, 0&, 0&)
        hOld = SelectObject(hDC, hBmp)
        Rtn = SetDIBits(hDC, hBmp, 0&, pxSize * 2, RGBBuff(1, 1), bi, DIB_RGB_COLORS)
        Call SelectObject(hDC, hOld)
        Call DeleteDC(hDC)
        If Rtn Then Set CreateCheckeredPattern = CreatePictureByhBmp(hBmp)
    End Function

(白茶) 2020/12/23(水) 15:03


まさか現物のまま提示いただけるとは思ってませんでした。
ありがとうございます。ちゃんと動きましたので。
なんか凄い複雑な内容ですね。塗り絵とかどうなってるんだか、
私にはレベルが高すぎて中身までは理解が及びませんが、
じっくりと勉強させていただきます。
ありがとうございました。
(花村) 2020/12/24(木) 00:29

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.