ExcelVBAでのkernel32(64bit)に関する問題と解決方法

このQ&Aのポイント
  • ExcelVBAでC++で作ったプログラムを動かす際にWindows7上のExcel2010でエラーメッセージが表示される場合、DeclareにPtrSafeを付ける必要があります。ただし、他のコードはそのままで問題ありません。
  • 32bitの場合はDeclareの関数宣言はそのまま使用して問題ありません。
  • Win32 API関数・定数の宣言について、コード中のLongには変更の必要はありません。
回答を見る
  • ベストアンサー

ExcelVBAでのkernel32(64bit)

今までExcel2000のVBAから、以下のようなコードを使ってC++で作ったコマンドプロンプトで動くプログラムを動かすプログラムを作っていましたが、これを64bitのWindows7上で動いているExcel2010で使おうとしたらメッセージが出ました。いろいろ調べてみたところ、たぶんDeclareにPtrSafeを付ければ良いようなのですが、その際、他のコードはそのままで良いのでしょうか。特に、コード中のLongはそのままで良いのか気になるのですが...。ちなみに、下記コードの条件コンパイルはネットで調べて見よう見まねで付けたもので、Excel2000のときには付けていないものでした。ご存じの方がいらっしゃいましたらご教授ください。 '------------------------------------------------------------------------------ ' Win32 API関数・定数の宣言 '------------------------------------------------------------------------------ #If VBA7 And Win64 Then '64bit Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _   ByVal dwMilliseconds As Long) As Long Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _   ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long #Else '32bit Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _   ByVal dwMilliseconds As Long) As Long Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _   ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long #End If Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF Private Const INFINITE As Long = &HFFFF '------------------------------------------------------------------------------ ' Run '------------------------------------------------------------------------------ Public Sub Run(ByVal project_name As String)   Dim program As String   Dim task_id As Long   Dim h_proc As Variant   program = mdlFunc.ProgramPath() & mdlFunc.ProgramOption(project_name) 'プログラム名   task_id = Shell(program, vbHide)   h_proc = OpenProcess(PROCESS_ALL_ACCESS, False, task_id)   If OpenProcess(PROCESS_ALL_ACCESS, False, task_id) <> vbNull Then     Call WaitForSingleObject(h_proc, INFINITE)     CloseHandle h_proc   End If End Sub

  • kary
  • お礼率95% (82/86)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

LongPtrの補足ですが、 32bit環境で動かした場合は、LongPtrは32bit、 64bit環境で動かした場合は、LongPtrは64bitとして扱われます。 上記の通りポインタは大きさが変わる物で、他言語ではある程度流動的に変わる仕様なのですが、 VB(VBA)の整数型(int, long)は常に大きさが変わらない仕様であったため、 今回のような事になったのでしょう。 >> OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある はい、そうです。 >> 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるLongで代用していた。 >> 2. 64bit環境ではアドレスが64bitになるので、32bitのLongに格納するとデータが欠落する。 >> 3. これの対策としてポインタとしてのLongPtrという型が追加された。 >> 4. 今回のプログラムの場合、OpenProcessがプロセスハンドルとしてアドレスを返す。 はい、そうです。 >> 5. これを受け取るデータ型はVariantなので問題ないが(自動で判別するから?)、 >> WaitForSingleObjectの第1引数及びCloseHandleには64bitのポインタを渡す必要がある。 Variantで問題があるかどうかは分かりませんが、 OpenProcess関数はHANDLE型を返しますので、受け側(h_proc)はLongPtrが適切だと思います。 >> 6. 結果、WaitForSingleObjectの第1引数とCloseHandleの引数をLongPtrにする必要がある。 はい、そうです。

参考URL:
http://msdn.microsoft.com/ja-jp/library/ee691831.aspx
kary
質問者

お礼

丁寧にお教えいただきありがとうございました。詳細なことはこれから勉強しようと思いますが、今回のポインタの件は何となく理解できたような気がします。

その他の回答 (2)

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.2

こんにちは。 APIの宣言自体は、Win32API_PtrSafe.TXTから持って来ればいいです。 http://www.microsoft.com/download/en/details.aspx?id=9970 C:\Office 2010 Developer Resources\Documents\Office2010Win32API_PtrSafe\Win32API_PtrSafe.TXT # それと、コード中のおかしな所は、直しました。 Public Sub Run(ByVal project_name As String)   Dim program As String   Dim task_id As Long   Dim h_proc As LongPtr   program = mdlFunc.ProgramPath() & mdlFunc.ProgramOption(project_name) 'プログラム名   task_id = Shell(program, vbHide)   h_proc = OpenProcess(PROCESS_ALL_ACCESS, 1, task_id)   If h_proc <> 0 Then     Call WaitForSingleObject(h_proc, INFINITE)     CloseHandle h_proc   End If End Sub

kary
質問者

お礼

ご回答いただきましてありがとうございます。ご紹介いただきましたtxtデータを見てみました。少しずつ勉強してみます。

回答No.1

ざっと見ておかしいのは、(*)のLongです。 64bit環境になってからは、これをLongPtrにする必要があるかと。 Declare PtrSafe Function WaitForSingleObject Lib "kernel32"(  ByVal hHandle As Long(*),  ByVal dwMilliseconds As Long) As Long dwMilliseconds側のLongはそのままです。 他も同様に、数値の値としてのLongはそのままで、ポインタやハンドルとしてのLongはLongPtrにしてみてください。

kary
質問者

お礼

ご回答いただきありがとうございます。いまいち正しく理解できているか判らないので確認させてください。 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるLongで代用していた。 2. 64bit環境ではアドレスが64bitになるので、32bitのLongに格納するとデータが欠落する。 3. これの対策としてポインタとしてのLongPtrという型が追加された。 4. 今回のプログラムの場合、OpenProcessがプロセスハンドルとしてアドレスを返す。 5. これを受け取るデータ型はVariantなので問題ないが(自動で判別するから?)、WaitForSingleObjectの第1引数及びCloseHandleには64bitのポインタを渡す必要がある。 6. 結果、WaitForSingleObjectの第1引数とCloseHandleの引数をLongPtrにする必要がある。 以上で間違いないでしょうか。お時間があれば確認していただけると幸いです。よろしくお願いいたします。

kary
質問者

補足

追加ですみません。OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある、という理解で間違いないでしょうか。

関連するQ&A

  • DataReport(PrintReport)の同期(待ち)について教えてください

    只今、VB6のDataReportを使用して500ページほど 印刷したいのですが100ページほどしか印刷されません。 原因は印刷が完了する前にDataReportの解放を行っているためです。 DataReportの解放前に数秒プログラムを停止させる方法があるのですが できればPrintreportメソッドで出力が完了したかの判断を行いたいです。 それに近い質問があり以下のように実行したのですがうまくいきませんでした。 具体的な解決方法があればとてもありがたいです。 【プログラムロジック.vbs】 '起動プロセスのオープン(状態の取得準備) Public Declare Function OpenProcess Lib "KERNEL32" _ (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long '起動プロセスとのシンクロ(待機する) Public Declare Function WaitForSingleObject Lib "KERNEL32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long '起動プロセスのクローズ(終了) Public Declare Function CloseHandle Lib "KERNEL32" _ (ByVal hObject As Long) As Long '起動プロセスが実行中か調べる(状態の取得) Public Declare Function GetExitCodeProcess Lib "KERNEL32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long Public Const SYNCHRONIZE = &H100000 Public Const INFINITE = &HFFFF 【プログラムロジック.frm】 Dim IDProcess As Long Dim hProcess As Long Dim ret As Long IDProcess = Control.PrintReport hProcess = OpenProcess(SYNCHRONIZE, 1, IDProcess) ret = WaitForSingleObject(hProcess, INFINITE) ret = CloseHandle(hProcess) 上記方法でテストしたのですが 「IDProcess」には「1」が返ります。 「hProcess」には「0」が返ります。 スプールにJOBがたまるまで「WaitForSingleObject」で WAITされると思ったのですがとくに待ちになりませんでした。 環境はWindowsXP、Windows2003サーバです。 よろしくお願いします。

  • UWSCがうまく動かない

    ExcelからUWSCを使って他のソフト2個を動かして又、Excelに 戻ってくるのですが、UWSCが重なって動作を同時に行う為、次のソフトで実行してみました。すると同時には動作せずに1個のプログラムの動作が終わって次ののプログラムを実行してくれて良くのですが、戻るときにExcelプログラムが真っ白に表示されて上の部分にファイル名と応答無と出てそれ以上進みません。UWSCソフトを終了すれば元には戻りますが、うまく操作をさせるにはどうすれば良いですか?よろしくお願いします。 UWSCの動きは⇒スタートボタンの横のタスクバーにあるソフトをクリックから始まり⇒終わったら又、Excelのタブをクリックして戻ります。 次のソフトはWebで見つけたソフトです。 外部プログラムの実行と処理待ち そこで、以下のサンプルマクロでは、Shell関数を使用して外部プログラムを実行し、そのプログラムが終了するまで待つように処理を施してあります。 *もうひとつの質問ですが、Win32 API関数の宣言はどこに記載をすればいいのですか? このままエディータに書けばいいのでしょうか '--- Win32 API 関数の宣言 --- Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _ ByVal dwMilliseconds As Long) As Long Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _ ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long '--- Win32 API 定数の宣言 --- Global Const PROCESS_ALL_ACCESS As Long = &H1F0FFF Global Const INFINITE As Long = &HFFFF Sub WaitRun() Dim TaskId As Long 'タスクID Dim hProc As Variant 'プロセスハンドル ' 外部プログラムの実行 TaskId = Shell("c:\Test.bat", 2) ' プロセスハンドルの取得 hProc = OpenProcess(PROCESS_ALL_ACCESS, False, TaskId) ' プロセスのオープン If OpenProcess(PROCESS_ALL_ACCESS, False, TaskId) <> vbNull Then ' プロセスのシグナル待ち Call WaitForSingleObject(hProc, INFINITE) ' プロセスクローズ CloseHandle hProc End If

  • GetProcessWorkingSetSizeでエラーが発生します

    VB6で画像処理アプリケーションの開発を行っている者です。 下記記述でワーキングセット領域を変更しようとしていますが、GetProcessWorkingSetSizeの部分でエラーが発生します。 使用PCにより、「問題が発生したため、Visual Basic を終了します。 ご不便をおかけして申し訳ありません。」や有無を言わさず開発環境が終了してしまう場合がありますが、いずれにしても原因が分かりません。 どなたかアドバイスいただけませんでしょうか? よろしくお願い致します。 (標準モジュールで宣言) Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Long Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long Declare Function GetProcessWorkingSetSize Lib "kernel32" (ByVal qq As Integer, ByVal pp As Integer, ByVal rr As Integer) As Long Declare Function SetProcessWorkingSetSize Lib "kernel32" (ByVal phph1 As Long, ByVal wkminwkmin1 As Long, ByVal wkmaxwkmax1 As Long) As Long Declare Function GetLastError Lib "kernel32.dll" () As Long (実行部) Sub WorkingSetChange() Dim id As Long 'アプリケーションプログラムのID用変数 Dim ph As Long 'アプリケーションプログラムのハンドル用変数 Dim wkmin As Long '最小ワーキングセット用変数 Dim wkmax As Long '最大ワーキングセット用変数 Dim bret As Long Const PROCESS_SET_QUOTA = &H100 Const PROCESS_QUERY_INFORMATION = &H400 'アプリケーションプログラムのIDを取得する id = GetCurrentProcessId() 'アプリケーションプログラムのハンドルをオープンする ph = OpenProcess(PROCESS_SET_QUOTA + PROCESS_QUERY_INFORMATION, False, id) 'アプリケーションプログラムの最大ワーキングセット値と最小ワーキングセット値を取得 bret = GetProcessWorkingSetSize(ph, wkmin, wkmax) '最小ワーキングセット値を1MBに設定 wkmin = 1 * 1024 * 1024 '最大ワーキングセット値を3MBに設定 wkmax = 3 * 1024 * 1024 'アプリケーションプログラムの最大ワーキングセット値と最小ワーキングセット値を変更 bret = SetProcessWorkingSetSize(ph, wkmin, wkmax) 'アプリケーションプログラムのハンドルをクローズする bret = CloseHandle(ph) End Sub

  • 64ビットエクセルでのAPI宣言/PtrSafe

    エクセルのInputboxで、入力された文字列を自動的にアスタリスクで隠すようにする方法を探し http://okwave.jp/qa/q2371878.html の回答No1のコードがまさに最適なコードで、これまで非常に助かっていました。 ところが、64bitのエクセルでは動かないことがわかりました。 表示されたエラーメッセージの言葉から調べて、PtrSafeという言葉を入れなければならないようなのでAPI宣言を以下のようにしてみました。 #If VBA7 And Win64 Then '64ビット版 Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long #Else '32ビット版 Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long #End If ところが、回答No1のコードで Sub Report_Open() を実行すると Public Function InputBoxDK(Prompt, Optional Title, Optional Default, Optional XPos, _ Optional YPos, Optional HelpFile, Optional Context) As String のところがハイライトされてエラーになります。 どう直せば良いのでしょうか? 全文のコードを乗せると字数制限に引っかかりますので、申し訳ありませんが宣言以外の部分は http://okwave.jp/qa/q2371878.html の回答No1のコードを見てくださいますようお願いします。

  • EXCELVBA フォルダ検索API

    エクセルからVBAでフォルダを選択させるコマンドを、APIを使ってフォルダ検索ダイアログボックスを出すまでは見よう見真似でできるのですが、このとき「あたらしいフォルダ」のボタンは必要ないので出したくないのですが、どこかに定数を指定すればよろしいかご存知でしたら教えてください。 (使用OS: Windows2000,Excel:2003) ちなみにコピペした宣言部分は以下のものです。 *************** Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _ (ByVal pidl As Long, ByVal pszPath As String) As Long Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As Long Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long) Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Public Const WM_USER = &H400 Public Const BFFM_SETSELECTIONA = (WM_USER + 102) Public Const BFFM_INITIALIZED = 1 ********************

  • ExcelVBAでフォームのタイトルバーで右クリックした場合などに閉じるボタンが有効化されないようにするコード

    Excelのプログラムで、最小化ボタンを有効にし、閉じるボタンを無効にする質問をしたんですが、うまくいったと思ったのですがフォームが開き、タイトルバーで右クリックした場合などは閉じるボタンが有効化されてしまうのでこれを無効のままにするコードを教えてください。 作ったプログラムは以下の通りです。 標準モジュール Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ (ByVal hWnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _ (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function DrawMenuBar Lib "user32" _ (ByVal hWnd As Long) As Long Public Declare Function GetSystemMenu Lib "user32.dll" _ (ByVal hWnd As Long, ByVal bRevert As Long) As Long Public Declare Function EnableMenuItem Lib "user32" _ (ByVal hMenu As Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long Public Const MF_DISABLED = &H2& Public Const GWL_STYLE = (-16) Public Const WS_MINIMIZEBOX = &H20000 Public Const MF_BYCOMMAND = &H0& Public Const SC_CLOSE = &HF060& Dim hSysMenu As Long UserForm_Initializeプロシージャ Dim fRet As Long Dim hWnd As Long Dim fStyle As Long hWnd = FindWindow("ThunderDFrame", "UserForm1") fStyle = GetWindowLong(hWnd, GWL_STYLE) fStyle = (fStyle Or WS_THICKFRAME Or WS_MINIMIZEBOX) fRet = SetWindowLong(hWnd, GWL_STYLE, fStyle) hSysMenu = GetSystemMenu(hWnd, 0) EnableMenuItem hSysMenu, SC_CLOSE, MF_BYCOMMAND Or MF_DISABLED fRet = DrawMenuBar(hWnd) 回答よろしくお願いします。

  • 「コンパイルエラー End Subが必要です。」

    Access2016でファイルを作成しているのですが、下記のVBAを実行しようとすると、「コンパイルエラー End Subが必要です。」とエラーメッセージが返ってきてしまいます。 構文の修正が必要であるとお気づきであれば、その箇所を教えていただけないでしょうか。初歩的な質問で恥ずかしい限りですが、何卒よろしくお願い致します。 Option Compare Database Option Explicit Public Declare PtrSafe Function SetWindowPos Lib "user32" _ (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _ ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, _ ByVal fuFlags As Long) As Long Public Declare PtrSafe Function GetSystemMenu Lib "user32" _ (ByVal hWnd As Long, ByVal fRever As Long) As Long Public Declare PtrSafe Function RemoveMenu Lib "user32" _ (ByVal hMenu As Long, ByVal uItem As Long, ByVal fuFlags As Long) As Long Public Const SWP_NOMOVE = &H2 Public Const SWP_NOSIZE = &H1 Public Const HWND_TOP = &H0 Public Const SC_SIZE = &HF000 Public Const SC_MAXIMIZE = &HF030 Public Const SC_CLOSE = &HF060 Public Const SC_RESTORE = &HF120 Public Const MF_BYCOMMAND = &H0& Public Sub test() Private Sub Form_Open(Cancel As Integer) Dim hWnd As Long hWnd = Application.hWndAccessApp SetWindowPos hWnd, HWND_TOP, 0, 0, 800, 600, SWP_NOMOVE hWnd = GetSystemMenu(hWnd, 0) RemoveMenu hWnd, SC_SIZE, MF_BYCOMMAND End Sub

  • VB6 二重起動確実防止について

    VB6 SP5にて2重起動確実な防止処理をいれようとCreateMutex 関数を使用しようと思っています。 CreateMutex 関数を埋め込んでEXEを実行すると 実際に対象となるプログラムが起動しているにも関わらず起動してしまいます。 何がいけないのか?検討がつかず困っています。 下記がプログラムになります。 何かわかりましたらご回答の程、よろしくお願い致します。 ***Win32API**************** Option Explicit ' CreateMutex 関数 Private Declare Function CreateMutex Lib "KERNEL32.DLL" Alias "CreateMutexA" ( _ ByRef lpMutexAttributes As Long, _ ByVal bInitialOwner As Long, _ ByVal lpName As String _ ) As Long ' CloseHandle 関数 Private Declare Function CloseHandle Lib "KERNEL32.DLL" ( _ ByVal hObject As Long _ ) As Long ************************************ SUB MAIN********************************* Public Sub Main() Dim hMutex As Long hMutex = CreateMutex(ByVal 0&, 0&, App.Title) On Error GoTo Err_Main If Err.LastDllError = 0 Then Dim cForm As Form1 Set cForm = New Form1 Call cForm.Show(vbModal) End If Err_Main: If hMutex <> 0 Then Call CloseHandle(hMutex) End If End Sub ************************************************

  • VBAにおける Option Explicitの役割

    VBAにおける Option Explicitの役割 VBAでゲームを作ることを勉強している初心者です。 本に従ってもっとも基本的なスロットゲームをためしました。 プログラム本体の前にある下記のOption Explicitを省くとコンパイルエラーになります。 VBAにおける Option Explicitはプログラム本体中にあるどのキーがどのスロットを止めるなどの指示を 具体的記述なしに有効にするなどの役目があるのでしょうか。 Option Explicit Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Declare Function GetTickCount Lib "kernel32" () As Long 'Windows起動後経過時間取得API どなたか教えていただけると助かります。 よろしくお願いいたします。

  • マウスのある個所の色

    お世話になります よろしくお願いします Pictureboxをクリックされたときに そのPictureboxがクリックされた箇所の色を16進数で取得したいのですが うまくいきません どこが間違っているのか教えてもらえないでしょうか? ソースは Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Type POINTAPI x As Long y As Long End Type Private Sub Picture1_Click() Dim Poi As POINTAPI Dim iro As Long GetCursorPos Poi iro = GetPixel(Me.Picture1.hdc, Poi.x, Poi.y) Me.Label2.Caption = Poi.x Me.Label3.Caption = Poi.y Me.Label1.Caption = iro CloseHandle (Me.Picture1.hdc) End Sub GetPixcelの引数に-1しか入りません あと、もし数値で取れたとして それを16進数にする方法を教えてください よろしくお願いします