[[20211227111911]] 『VBA ユーザーフォームのイメージコントロール内に』(マカロニグラタン) ページの最後に飛ぶ

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

 

『VBA ユーザーフォームのイメージコントロール内に図形を描画させたい』(マカロニグラタン)

こんにちは。うまく伝わるといいのですが、下記のようなことを
やりたいと思っています。

図形のテスト問題をVBAのユーザーフォームを用いて作成しています。

テスト問題はユーザーフォーム内のイメージコントロール(Image1)内に
画像を呼び出して表示させています。
例えば正方形の図形を画像として一つ表示させています。
テスト問題として「対角線を入力しなさい」と出題したとします。

回答者はそのイメージコントロール内に線分を入力します(1点目クリック、2点目をクリックのような感じで)。

書かれた線分の位置を記録して合っていれば正解、間違っていれば不正解と表示
します。
(人によって多少ずれるとは思いますので許容範囲は持たせようと思います。)

今回の質問は・・
1.イメージコントロール内をクリックして線分を書かせる方法
2.記述した線分の座標位置を取得する方法

を知りたいです。(そもそもできるかもわからないですが・・)

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


 APIだと↓こんな感じの記事が引っ掛かりましたよ。
 なんか準備が大変そうですね...(やった事ないからそう見えるだけかも知れませんが^^;)

Excel Gamer - Shadow Slash Chapter.134 [ APIによる描画処理6:図形描画実践編 ]
http://shadowslasheizan.blog114.fc2.com/blog-entry-160.html

(白茶) 2021/12/27(月) 11:49


 ちょっと待ち時間ができたので、自身の勉強がてら見様見真似で書いてみまたモノを貼っときます。
 (いまだにあんまり理解してません^^; 正直「合ってんのか?コレ...」って感じです)

    Option Explicit
    Private Type POINTAPI
        X As Long
        Y As Long
    End Type
    Private Type LOGPEN
        lopnStyle As Long
        lopnWidth As POINTAPI
        lopnColor As Long
    End Type
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Private Declare PtrSafe Function WindowFromAccessibleObject Lib "oleacc.dll" (ByVal IAcessible As Object, ByRef hwnd As LongPtr) As Long
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function ScreenToClient Lib "user32" (ByVal hwnd As LongPtr, lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
    Private Declare PtrSafe Function SelectObject Lib "gdi32" (ByVal hDC As LongPtr, ByVal hObject As LongPtr) As LongPtr
    Private Declare PtrSafe Function DeleteObject Lib "gdi32" (ByVal hObject As LongPtr) As Long
    Private Declare PtrSafe Function CreatePenIndirect Lib "gdi32" (lpLogPen As LOGPEN) As LongPtr
    Private Declare PtrSafe Function MoveToEx Lib "gdi32" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long, lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function LineTo Lib "gdi32" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long) As Long
    Private Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function InvalidateRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT, ByVal bErase As Long) As Long
    Private Const PS_SOLID = 0
    Private Const PS_DASH = 1        '  -------
    Private Const PS_DOT = 2         '  .......
    Private Const PS_DASHDOT = 3     '  _._._._
    Private Const PS_DASHDOTDOT = 4  '  _.._.._
    Private Const PS_NULL = 5
    Private Const PS_INSIDEFRAME = 6
    Private Const PS_USERSTYLE = 7
    Private Const PS_ALTERNATE = 8
    Private Const PS_STYLE_MASK = &HF&
    Private WithEvents Image1 As MSForms.Image, WithEvents BtnClear As MSForms.CommandButton
    Private Label1 As MSForms.Label
    Private LabelPos1 As MSForms.Label, LabelPos2 As MSForms.Label
    Private hDC As LongPtr
    Private Flg As Boolean, pt As POINTAPI
    Private Property Get fmhwnd() As Long
        WindowFromAccessibleObject Me, fmhwnd
    End Property
    Private Sub BtnClear_Click()
        Dim r As RECT
        GetClientRect fmhwnd, r
        InvalidateRect fmhwnd, r, 0&
        LabelPos1.Caption = "始点:"
        LabelPos2.Caption = "終点:"
    End Sub
    Private Sub Image1_Click()
        Dim cur As POINTAPI
        GetCursorPos pt
        ScreenToClient fmhwnd, pt
        Flg = Not Flg
        If Flg Then
            MoveToEx hDC, pt.X, pt.Y, cur
            LabelPos1.Caption = "始点:" & pt.X & "/" & pt.Y
            LabelPos2.Caption = "終点:"
        Else
            LabelPos2.Caption = "終点:" & pt.X & "/" & pt.Y
            Dim p As POINTAPI, pn As LOGPEN, hPen As LongPtr, hPenOld As LongPtr
            p.X = 3
            pn.lopnStyle = PS_SOLID
            pn.lopnWidth = p
            pn.lopnColor = &HFF&
            hPen = CreatePenIndirect(pn)
            hPenOld = SelectObject(hDC, hPen)
            LineTo hDC, pt.X, pt.Y
            SelectObject hDC, hPenOld
            DeleteObject hPen
        End If
    End Sub
    Private Sub UserForm_Initialize()
        Set Image1 = Me.Controls.Add("Forms.Image.1", "Image1")
        With Image1
            .Top = 3
            .Left = 3
            .Width = 108
            .Height = 108
            .MousePointer = fmMousePointerCross
    '        .Picture = LoadPicture("C:\xxx\test.bmp")
        End With
        Set Label1 = Me.Controls.Add("Forms.Label.1", "Label1")
        With Label1
            .Top = 108 + 3
            .Left = 3
            .Width = 108
            .Caption = "対角線を入力しなさい"
            .TextAlign = fmTextAlignCenter
        End With
        Set LabelPos1 = Me.Controls.Add("Forms.Label.1", "LabelPos1")
        With LabelPos1
            .Top = 3
            .Left = 108 + 6
            .Width = 72
        End With
        Set LabelPos2 = Me.Controls.Add("Forms.Label.1", "LabelPos2")
        With LabelPos2
            .Top = 3 + 15
            .Left = 108 + 6
            .Width = 72
        End With
        Set BtnClear = Me.Controls.Add("Forms.CommandButton.1", "BtnClear")
        With BtnClear
            .Top = 48 + 3
            .Left = 108 + 6
            .Width = 72
            .Caption = "クリア"
        End With
        BtnClear_Click
        hDC = GetDC(fmhwnd)
    End Sub

    Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
        If Flg Then Image1_Click
        ReleaseDC fmhwnd, hDC
    End Sub

(白茶) 2021/12/27(月) 23:45


 (白茶)さん...ちゃんと動いてますよ〜面白〜イ。		
 (白茶)さんの書かれたコードを一箇所だけ変更して(内容一緒)…遊ばせていただきました。(_ _)ペコッ		

 Private Sub Image1_Click()		
    Dim cur As POINTAPI		
    GetCursorPos pt		
    ScreenToClient fmhwnd, pt		
    Flg = Not Flg		
    If Flg Then		
            MoveToEx hDC, pt.x, pt.y, cur		
            With LabelPos1		
                    LabelPos1 = "クリック位置座標 始点: x=" & pt.x & "  y=" & pt.y		
                    .Top = 3		
                    .Left = 108 + 6		
                    .Width = 150		
            End With		
    Else		
            Dim p As POINTAPI, pn As LOGPEN, hPen As LongPtr, hPenOld As LongPtr		
            p.x = 3		
            pn.lopnStyle = PS_SOLID		
            pn.lopnWidth = p		
            pn.lopnColor = &HFF&		
            hPen = CreatePenIndirect(pn)		
            hPenOld = SelectObject(hDC, hPen)		
            LineTo hDC, pt.x, pt.y		
            SelectObject hDC, hPenOld		
            DeleteObject hPen		
            With LabelPos2		
                    LabelPos2 = "クリック位置座標 終点: x=" & pt.x & "  y=" & pt.y		
                    .Top = 3 + 15		
                    .Left = 108 + 6		
                    .Width = 150		
            End With		
    End If		
 End Sub		

 (白茶)さん…ありがとうございます。		

 つい、閲覧してしまった方ヘ...オモチどうぞ♪ (*・v・)_Ω~  		
 良いお年を〜。+゜		

(あみな) 2021/12/28(火) 15:43


コメント返信:

[ 一覧(最新更新順) ]


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