拡大鏡(V) <TOP>
虫眼鏡を作成します。 拡大鏡(T)と同じですが、拡大・縮小およびスムーズ拡大(?)、終了を右クリックで選択できるようにしてみました。
SystemParametersInfo システム全体に関するパラメータを取得・設定
GetCursorPos
マウスカーソル(マウスポインタ)の現在の位置に相当するスクリーン座標を取得
SendMessage
メッセージを送る
SetWindowPos
ウィンドウの状態を設定
ReleaseCapture
マウスキャプチャの解放
GetDesktopWindow
デスクトップのウィンドウハンドル取得
StretchBlt
画像の拡大転送
GetDC
ウィンドウハンドルからデバイスコンテキストを取得
ReleaseDC デバイスコンテキストを解放
CreatePolygonRgn
多角形のリージョンを作成
CreateEllipticRgn
楕円形のリージョンを作成
CreateRectRgn
長方形のリージョンを作成
CreateRoundRectRgn
角の丸い長方形のリージョンを作成
CombineRgn
既存の二つの領域を結合して新しい領域を作成
SetWindowRgn
指定の領域をウィンドウ領域として設定
SetStretchBltMode
指定されたデバイスコンテキストのビットマップ伸縮モードを設定
AnimateWindow
フォームをアニメーション表示
メインフォーム(200×200)にピクチュアボックス(200×200)を重ね合わせます。
ルーペは8〜12角形を選んでください(例では12角形)。角数が多いと円形に近くなり、少ない場合は枠より円のほうが大きくなります。
ルーペ倍率は初期で2倍に設定しています。カーソルの部分を拡大します。
ルーペの移動は、青いフレーム部分をドラッグ します。
フレーム(青い枠)部を右クリックすると、クリックした位置を左上とする設定ポップアップメニュー(Form2)が表示されます。
拡大縮小 |
スクロールバーで指定します。拡大縮小率は、その都度表示されます。 |
拡大縮小範囲 |
0.8倍 〜 4倍 |
通常拡大 |
StretchBltでの拡大縮小転送です。 |
スムーズ |
SetStretchBltModeを使って綺麗に(?)拡大縮小します。 |
設定終了 |
ポップアップメニューを消します。 |
ルーペの終了 |
アニメーション終了(あまり効いていません)させています。 |
左:元の写真 中:通常拡大 右:スムーズ拡大
参考
LOUPE4.LZHをダウンロードするとF-Basicをお持ちでない方でも試用できます。
'================================================================ '= 虫眼鏡 (リージョン:MainForm12角形) '= MainForm、Picture1は同サイズ重ね合わせ '= (Loupe4.bas) '================================================================ #include "Windows.bi" Type POINTAPI x As Long y As Long End Type Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type ' システム全体に関するパラメータを取得・設定 Declare Function Api_SystemParametersInfo& Lib "user32" Alias "SystemParametersInfoA" (ByVal uiAction&, ByVal uiParam&, pvParam As RECT, ByVal fWinIni&) ' マウスカーソル(マウスポインタ)の現在の位置に相当するスクリーン座標を取得 Declare Function Api_GetCursorPos& Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) ' ウィンドウにメッセージを送信。この関数は、指定したウィンドウのウィンドウプロシージャが処理を終了するまで制御を返さない Declare Function Api_SendMessage& Lib "user32" Alias "SendMessageA" (ByVal hWnd&, ByVal wMsg&, ByVal wParam&, lParam As Any) ' ウィンドウのサイズ、位置、および Z オーダーを設定 Declare Function Api_SetWindowPos& Lib "user32" Alias "SetWindowPos" (ByVal hWnd&, ByVal hWndInsertAfter&, ByVal X&, ByVal Y&, ByVal CX&, ByVal CY&, ByVal uFlags&) ' マウスのキャプチャを解放 Declare Function Api_ReleaseCapture& Lib "user32" Alias "ReleaseCapture" () ' Windowsのデスクトップウィンドウを識別。返されるポインタは、一時的なポインタ。後で使用するために保存しておくことはできない Declare Function Api_GetDesktopWindow& Lib "user32" Alias "GetDesktopWindow" () ' 拡縮をともなうグラフィックデバイス間のイメージを転送 Declare Function Api_StretchBlt& Lib "gdi32" Alias "StretchBlt" (ByVal hDC&, ByVal X&, ByVal Y&, ByVal nWidth&, ByVal nHeight&, ByVal hSrcDC&, ByVal xSrc&, ByVal ySrc&, ByVal nSrcWidth&, ByVal nSrcHeight&, ByVal dwRop&) ' 指定されたウィンドウのクライアント領域または画面全体を表すディスプレイデバイスコンテキストのハンドルを取得 Declare Function Api_GetDC& Lib "user32" Alias "GetDC" (ByVal hWnd&) ' デバイスコンテキストを解放 Declare Function Api_ReleaseDC& Lib "user32" Alias "ReleaseDC" (ByVal hWnd&, ByVal hDC&) ' 多角形のリージョンを作成 Declare Function Api_CreatePolygonRgn& Lib "gdi32" Alias "CreatePolygonRgn" (lppt As POINTAPI, ByVal nCount&, ByVal nPolyFillMode&) ' 楕円形のリージョンを作成 Declare Function Api_CreateEllipticRgn& Lib "gdi32" Alias "CreateEllipticRgn" (ByVal nLeftRect&, ByVal nTopRect&, ByVal nRightRect&, ByVal nBottomRect&) ' 長方形のリージョンを作成 Declare Function Api_CreateRectRgn& Lib "gdi32" Alias "CreateRectRgn" (ByVal nLeftRect&, ByVal nTopRect&, ByVal nRightRect&, ByVal nBottomRect&) ' 角の丸い長方形のリージョンを作成 Declare Function Api_CreateRoundRectRgn& Lib "gdi32" Alias "CreateRoundRectRgn" (ByVal nLeftRect&, ByVal nTopRect&, ByVal nRightRect&, ByVal nBottomRect&, ByVal nWidthEllipse&, ByVal nHeightEllipse&) ' 既存の二つの領域を結合して新しい領域を作成 Declare Function Api_CombineRgn& Lib "gdi32" Alias "CombineRgn" (ByVal hRgnDest&, ByVal hRgnSrc1&, ByVal hRgnSrc2&, ByVal nCombineMode&) ' 指定の領域をウィンドウ領域として設定 Declare Function Api_SetWindowRgn& Lib "user32" Alias "SetWindowRgn" (ByVal hWnd&, ByVal hRgn&, ByVal bRedraw&) ' 指定されたデバイスコンテキストのビットマップ伸縮モードを設定 Declare Function Api_SetStretchBltMode& Lib "gdi32" Alias "SetStretchBltMode" (ByVal hDC&, ByVal nStretchMode&) ' フォームをアニメーション表示 Declare Function Api_AnimateWindow& Lib "user32" Alias "AnimateWindow" (ByVal hWnd&, ByVal dwTime&, ByVal dwFlags&) #define COLORONCOLOR 3 #define FORM_HIDE &H80000 Or &h10000 '複合操作 #define HALFTONE 4 'ハーフトーン #define HTCAPTION 2 'タイトルバーをクリックしたことを示す #define INDING 2 '全域モード(塗りつぶし) #define MF_STRING &H0 '文字列 #define RCCOPY &HCC0020 '転送元長方形を転送先長方形にそのままコピー #define TPM_LEFTALIGN &H0 'ショートカットメニューの左端を、xパラメータが指定する座標に合わせる #define TPM_RETURNCMD &H100 '関数の戻り値として、ユーザーが選択したメニュー項目のIDを返す #define TPM_RIGHTBUTTON &H2 'マウスの右ボタンでポップアップメニューからの選択が行えるようにする #define WN_NCLBUTTONDOWN &HA1 '非クライアント領域で左マウスボタンを押す #define WND_TOPMOST -1 ' #define SWP_NOACTIVATE &H10 'ウィンドウをアクティブにしない #define SWP_SHOWWINDOW &H40 'ウィンドウを表示する #define SPI_GETWORKAREA 48 Var Shared dhDC As Long 'デスクトップデバイスコンテキスト Var Shared phDC As Long 'ピクチャボックスデバイスコンテキスト Var Shared srcXY As Integer Var Shared hMenu As Long Var Shared Flag As Long Var Shared pa As POINTAPI Var Shared rc As RECT '---------- MainForm -------------------------------------------- Var Shared Picture1 As Object Var Shared Timer1 As Object Picture1.Attach GetDlgItem("Picture1") Timer1.Attach GetDlgItem("Timer1") '---------- Form2 ----------------------------------------------- Var Shared Form2 As Object Var Shared Text1 As Object Var Shared HScroll1 As Object Var Shared Check1 As Object Var Shared Button1 As Object Var Shared Button2 As Object '================================================================ '= '================================================================ Declare Sub MainForm_Start edecl () Sub MainForm_Start() Var i As Integer Var Corner As Byte '角の数 Var Rad As Double '角度 Var Rgn1 As Long '外枠 Var Rgn2 As Long '円形 Var Ret As Long 'ワークエリア取得 Ret = Api_SystemParametersInfo(SPI_GETWORKAREA, 0, rc, 0) Flag = 0 '外周(8〜12) Corner = 12 'Corner角形の頂点位置 Var xy(Corner) As POINTAPI srcXY = 100 'デスクトップハンドル取得 DtphWnd = Api_GetDesktopWindow() 'PictureBoxデバイスコンテキスト取得 phDC = Api_GetDC(Picture1.GethWnd) 'デスクトップデバイスコンテキスト取得 dhDC = Api_GetDC(DtphWnd) 'ひとつ分の角度 Rad = 3.1415926 / (Corner / 2) For i = 0 To Corner - 1 xy(i).x = Sin(Rad * i) * (GetWidth / 2) + (GetWidth / 2) xy(i).y = Cos(Rad * i) * (GetHeight / 2) + (GetHeight / 2) Next i '外枠 Rgn1 = Api_CreatePolygonRgn(xy(0), Corner, INDING) Ret = Api_SetWindowRgn(GethWnd, Rgn1, -1) '円形 Rgn2 = Api_CreateEllipticRgn(10, 10, GetWidth - 9, GetHeight - 9) Ret = Api_SetWindowRgn(Picture1.GethWnd, Rgn2, -1) Ret = Api_SetWindowPos(GethWnd, WND_TOPMOST, 0, 0, GetWidth, GetHeight, SWP_SHOWWINDOW Or SWP_NOACTIVATE) '形状設定後表示 ShowWindow -1 Timer1.SetInterval 10 Timer1.Enable -1 End Sub '================================================================ '= カーソル位置のデスクトップ画像を拡大して転送 '================================================================ Declare Sub Timer1_Timer edecl () Sub Timer1_Timer() Var Ret As Long Ret = Api_GetCursorPos(pa) If Flag = 0 Then 'そのまま拡大縮小 Ret = Api_SetStretchBltMode(phDC, COLORONCOLOR) Else '綺麗に拡大縮小 Ret = Api_SetStretchBltMode(phDC, HALFTONE) End if Ret = Api_StretchBlt(phDC, 0, 0, 200, 200, dhDC, pa.x - (srcXY / 2), pa.y - (srcXY / 2), srcXY, srcXY, RCCOPY) End Sub '================================================================ '= '================================================================ Declare Sub MainForm_MouseDown edecl (Button As Integer, Shift As Integer, x As Single, y As Single) Sub MainForm_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) Var Ret As Long Ret = Api_ReleaseCapture() Ret = Api_SendMessage(GethWnd, WN_NCLBUTTONDOWN, HTCAPTION, 0) End Sub '================================================================ '= 設定フォーム '================================================================ Declare Sub MainForm_MouseUp edecl (Button As Integer, Shift As Integer, x As Single, y As Single) Sub MainForm_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single) Var Flags As Long Var Ret As Long If Not(CheckObject(Form2)) Then Form2.CreateWindow "Form2", -1 Text1.Attach Form2.GetDlgItem("Text1") : Text1.SetFontSize 14 HScroll1.Attach Form2.GetDlgItem("HScroll1") Check1.Attach Form2.GetDlgItem("Check1") : Check1.SetFontSize 14 Button1.Attach Form2.GetDlgItem("Button1") : Button1.SetFontSize 14 Button2.Attach Form2.GetDlgItem("Button2") : Button2.SetFontSize 14 Form2.SetTopMostWindow -1 'マウスカーソルの位置を取得 Ret = Api_GetCursorPos(pa) '設定画面(Form2)が、ワークエリア外に位置する場合の処理 If pa.x + Form2.GetWidth > rc.Right And pa.y + Form2.GetHeight > rc.Bottom Then '縦横共にエリア外の場合 Form2.MoveWindow rc.Right - 200, rc.Bottom - 130 Else If pa.x + Form2.GetWidth > rc.Right Then '横のみエリア外の場合 Form2.MoveWindow rc.Right - 200, pa.y Else If pa.y + Form2.GetHeight > rc.Bottom Then '縦のみエリア外の場合 Form2.MoveWindow pa.x, rc.Bottom - 130 Else 'アリア内の場合 Form2.MoveWindow pa.x, pa.y End If HScroll1.SetScrollRange 50, 250 HScroll1.SetScrollStep 10, 10 HScroll1.SetScrollPos 300 - srcXY Text1.SetWindowText "拡大縮小率:" & Format$(200 / srcXY, "#.#") Check1.SetCheck Flag Flag = Check1.GetCheck End If End Sub '================================================================ '= スムーズ処理 '================================================================ Declare Sub Check1_on edecl () Sub Check1_on() Flag = Check1.GetCheck End Sub '================================================================ '= 拡大率設定 '================================================================ Declare Sub HScroll1_Change edecl () Sub HScroll1_Change() srcXY = 300 - HScroll1.GetScrollPos Text1.SetWindowText "拡大縮小率:" & Format$(200 / srcXY, "#.#") End Sub '================================================================ '= 設定終了 '================================================================ Declare Sub Button1_on edecl () Sub Button1_on() Form2.DestroyWindow Text1.Detach HScroll1.Detach Check1.Detach Button1.Detach Button2.Detach End Sub '================================================================ '= 拡大鏡の終了 '================================================================ Declare Sub Button2_on edecl () Sub Button2_on() Form2.DestroyWindow Text1.Detach HScroll1.Detach Check1.Detach Button1.Detach Button2.Detach Ret = Api_ReleaseDC(Picture1.GethWnd, phDC) Ret = Api_ReleaseDC(DtphWnd, dhDC) Ret = Api_AnimateWindow(GethWnd, 1000, FORM_HIDE) End End Sub '================================================================ '= '================================================================ While 1 WaitEvent Wend Stop End