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

このQ&Aのポイント
  • 64ビットエクセルでのAPI宣言/PtrSafeに関する質問です。
  • エクセルのInputboxで、入力された文字列を自動的にアスタリスクで隠す方法を探しています。
  • 質問者は回答No1に掲載されているコードが助かっていたが、64ビットのエクセルでは動作しないことに気づきました。質問者はPtrSafeという言葉を調べ、API宣言を変更しましたが、エラーが発生しています。
回答を見る
  • ベストアンサー

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のコードを見てくださいますようお願いします。

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

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

(1/2) こんにちは。 暫く回答お休み中で、質問を読むこともないこの頃なのですが、 たまたま馴染みのアバターをお見かけしましたので、このご質問だけレスしてみます。 Win32 API コールバック、と、64|32bit環境互換については 今の時点での情報が少な過ぎてこちらも確信を持てるものは書けません。 必要な手当てをして、動作確認はしましたが、もっとスマートなやり方があるかも知れません。 お求めに寄り添った直接的な回答として、2回の投稿で記述を掲げますが、 そもそもの方法として、これが唯一のものではないことを知っておいてください。 リンクを張られた質問スレ(元スレ)においては、 「恐らくAccess VBAついての質問であろう」とう前提で回答が付いています。 今回は、Excel カテゴリに書かれた質問ですから、 PasswordCharプロパティを * に設定したTextBoxを配置したユーザーフォーム (他にPromptを表示するLabel、OKボタンにあたるCommandButton)を用意しておいて、 ' ' 標準モジュール Public rtn Sub Report_Open()   UserForm1.Show vbModal   If rtn <> "password" Then     MsgBox "社員コードが間違っています。"   End If End Sub ' ' ユーザーフォームモジュール Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)   rtn = TextBox1 End Sub Private Sub CommandButton1_Click()   Unload Me End Sub のようなものを奨めるのがExcel VBA的には本筋だと考えています。 この場合はバージョン互換を意識する必要はありませんし、デザインが自在ですし、 何よりシンプルです。 本題に戻って、、、 AddressOf演算子に渡すFunctionの型は明示的である必要があります。 64bitでは Function NewProc(...) As LongPtr 32bitでは Function NewProc(...) As Long なので、各関数を丸ごと条件付きコンパイルの内側で書き分けてあげる必要があります。 もしも仮に32bit互換を捨てて、64bit環境に限った話としては、 64bit用のDeclare文のすべてと、 各Functionの戻り型、引数、変数について、 Long型の宣言をLongPtr型に(今回必要な記述に関してのみ) ご提示の記述から全置換すれば期待の動作にはなります。 64bit版については、明らかにLongLong型である場合でも、 LongPtr型で統一して解り易い(編集し易い)ように書いています。 以下、お求めの記述。 ' ' /// Option Explicit 'Constants to be used in our API functions Private Const EM_SETPASSWORDCHAR = &HCC Private Const WH_CBT = 5 Private Const HCBT_ACTIVATE = 5 Private Const HC_ACTION = 0 #If VBA7 And Win64 Then  '〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 ' ' 〓〓〓〓〓64ビット版、以下〓〓〓〓〓 Private Declare PtrSafe Function CallNextHookEx Lib "user32" ( _     ByVal hHook As LongPtr, ByVal ncode As LongPtr, _     ByVal wParam As LongPtr, lParam As Any _     ) As LongPtr Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _     ByVal lpModuleName As String _     ) As LongPtr Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _     ByVal idHook As LongPtr, ByVal lpfn As LongPtr, _     ByVal hmod As LongPtr, ByVal dwThreadId As LongPtr _     ) As LongPtr Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _     ByVal hHook As LongPtr _     ) As LongPtr Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" ( _     ByVal hDlg As LongPtr, ByVal nIDDlgItem As LongPtr, _     ByVal wMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr _     ) As LongPtr Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" ( _     ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As LongPtr _     ) As LongPtr Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As LongPtr Private Const VER64BIT = True Private hHook As LongPtr Private Function NewProc(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr   Dim strClassName As String   Dim RetVal As LongPtr   Dim lngBuffer As LongPtr   If lngCode < HC_ACTION Then     NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)     Exit Function   End If   strClassName = String$(256, " ")   lngBuffer = 255   If lngCode = HCBT_ACTIVATE Then 'A window has been activated     RetVal = GetClassName(wParam, strClassName, lngBuffer)     If Left$(strClassName, CLng(RetVal)) = "#32770" Then 'Class name of the Inputbox       'This changes the edit control so that it display the password character *.       'You can change the Asc("*") as you please.       SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0     End If   End If   'This line will ensure that any other hooks that may be in place are   'called correctly.   CallNextHookEx hHook, lngCode, wParam, lParam End Function

emaxemax
質問者

お礼

cj_mover さん、いつもありがとうございます。 アバタじゃなくてえくぼ、いやホクロなんですが・・・なんて冗談はおいときまして、さっそく64bitエクセルで試したところ当然ですがちゃんと作動してくれました。 助かりました。 本当はおっしゃるようにユーザーフォームを使用するべきなんですね。ただユーザーフォームってこれまでつかったことがないのでなんとなく尻込みしていました。 ユーザーフォームの方も試してみて、またわからないことがありましたら質問させていただきます。 ありがとうございました。

その他の回答 (1)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

(2/2) Public Function InputBoxDK( _     Prompt As String, Optional Title, Optional Default, _     Optional XPos, Optional YPos, Optional HelpFile, Optional Context _     ) As String   Dim lngModHwnd As LongPtr   Dim lngThreadID As LongPtr   lngThreadID = GetCurrentThreadId   lngModHwnd = GetModuleHandle(vbNullString)   hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)   InputBoxDK = InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, Context)   UnhookWindowsHookEx hHook End Function ' ' 〓〓〓〓〓64ビット版、以上〓〓〓〓〓 #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 Private Const VER64BIT = False Private hHook As Long Private Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long   Dim strClassName As String   Dim RetVal As Long   Dim lngBuffer As Long   If lngCode < HC_ACTION Then     NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)     Exit Function   End If   strClassName = String$(256, " ")   lngBuffer = 255   If lngCode = HCBT_ACTIVATE Then 'A window has been activated     RetVal = GetClassName(wParam, strClassName, lngBuffer)     If Left$(strClassName, CLng(RetVal)) = "#32770" Then 'Class name of the Inputbox       'This changes the edit control so that it display the password character *.       'You can change the Asc("*") as you please.       SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0     End If   End If   'This line will ensure that any other hooks that may be in place are   'called correctly.   CallNextHookEx hHook, lngCode, wParam, lParam End Function Public Function InputBoxDK( _     Prompt As String, Optional Title, Optional Default, _     Optional XPos, Optional YPos, Optional HelpFile, Optional Context _     ) As String   Dim lngModHwnd As Long   Dim lngThreadID As Long   lngThreadID = GetCurrentThreadId   lngModHwnd = GetModuleHandle(vbNullString)   hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)   InputBoxDK = InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, Context)   UnhookWindowsHookEx hHook End Function ' ' 〓〓〓〓〓32ビット版、以上〓〓〓〓〓 #End If  '〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 ' ' 〓〓〓〓〓 Sub Report_Open()   If InputBoxDK("パスワードを入力して下さい") <> "password" Then     MsgBox "社員コードが間違っています。"   End If '  Debug.Print VER64BIT ' 確認用 64bit環境なら True End Sub ' ' 〓〓〓〓〓

emaxemax
質問者

お礼

ありがとうございました。

関連するQ&A

  • 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での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

  • WinAPIで電卓をクリック

    現在、WinAPIを勉強しており、練習としてVBAを用いて、電卓アプリのボタンをクリックしようとしています。 キーを送るのではなく、クリックで行いたいたいと 考えています。 ボタンのハンドルを取得するところまではできましたが、sendMessageでクリックできず、EditBoxに数字が 入りません。 どのようにすればよいのかご教授ください。 よろしくお願い致します。 環境: WinXP home、 Excel2002、Win付属アプリの電卓v5.1 ---作成したプログラム---- '標準モジュールの中身 Option Explicit Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As Long) As Long Private Const WM_LBUTTONDOWN = &H201 Private Const WM_LBUTTONUP = &H202 Sub Main() Dim lngWindWnd As Long 'ウィンドウハンドル Dim ret As Long Dim hCalc As Long 'アプリケーションタイトルより、ウィンドウハンドルを得ます lngWindWnd = FindWindow(vbNullString, "電卓") '8ボタンのハンドル(確実に取れていることを確認 hCalc = FindWindowEx(lngWindWnd, 0, "Button", "8") ret = SetForegroundWindow(lngWindWnd) ret = SendMessage(hCalc, WM_LBUTTONDOWN, 0, 0) End Sub

  • Excel VBAでアプリのウィンドウ名取得

    WindowsXP, Excel2007で、ExcelからIE8にキーコードを送りたいです。 ネットで拾った以下のコードにより、 Option Explicit Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Function activate_win(win_name As String) As Long Dim hwindow As Long hwindow = FindWindow(vbNullString, win_name) If hwindow <> 0 Then SetForegroundWindow hwindow activate_win = hwindow End Function Call activate_win("ウィンドウ名") Sendkeys "ABC", True のような形で、メモ帳での動作は確認したのですが、 IEだとウィンドウがアクティブになってくれません。 おそらくウィンドウタイトルを間違えているのだと思われますが、 全角半角などを変えてみたりしても、どう見比べてみても間違いがわかりません。 見た目ではわからない、似た文字だが違うということではないかと思っています。 そこで、開いているアプリのウィンドウ名すべてをメモ帳に書き出すような (あるいは任意のアプリにペーストできるようにするような)コードはないでしょうか? よろしくお願いします

  • VBAでSetTextColorがうまくいかない

    EXCELのVBAでユーザーフォームを使ったグラフィック表示のプログラムを 作っているのですが、SetTextColorでテキスト色の設定をしようと してもうまくいきません。何故か設定しようとする色の値が無視されて 「1304008」が設定されてしまいます。(GetTextColorで確認) そしてそれ以降何を設定してもこの状態のままです。 何か考えられることがありますでしょうか。 下にそのプログラムを示します。 ちなみにSetBKColorやAngleArcなど他のグラフィック命令は問題なく 動いていてSetTextColorだけがうまくいってない状態です。 '------------------------------------------------- ' ユーザーフォーム用プログラム '------------------------------------------------- Private Declare Function GetActiveWindow Lib "user32" () As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hwndParent As Long, _ ByVal hwndChildAfter As Long, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) As Long Private Declare Function GetDC Lib "user32" ( _ ByVal hWnd As Long) As Long Private Declare Function ReleaseDC Lib "user32" ( _ ByVal hWnd As Long, _ ByVal hdc As Long) As Long Private Declare Function SetTextColor Lib "gdi32" _ (ByVal hdc As Long, crColor As Long) As Long Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" _ (ByVal hdc&, ByVal x&, _ ByVal y&, ByVal lpString$, ByVal nCount&) As Long Dim hWnd As Long Dim hdc As Long Public Sub UserForm_Activate() DoEvents hWnd = FindWindowEx(GetActiveWindow, 0, "F3 Server 60000000", "") hdc = GetDC(hWnd) ret = SetTextColor(hdc, RGB(255, 0, 0)) ret = TextOut(hdc, 0, 0, "abc", 3) Call ReleaseDC(hWnd, hdc) End Sub '-------------------------------------------------

  • APIを使う時は参照設定は不要?

    例えば Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Sub test() Dim Handle As Long Handle = FindWindow("IEFrame", vbNullString) Debug.Print Handle End Sub と言うコードでウィンドウハンドルを取得する場合、 参照設定のどこにもチェックを入れませんが、なぜ参照設定しなくても使えるのでしょうか? Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long が参照設定の代わりになるのですか?

  • エクセルのマクロで教えて下さい

    エクセルのマクロでプリンタ名を取得しています エクセルの32ビット版と64ビット版で共用できるように下記の記述をしたのですが 32ビット版は問題ないのですが、64版ではエラーが発生します エラーの原因がわかれば教えて下さい Option Explicit 'このEnumprintersとMoveMemoryがWin32 API の宣言です。 #If VBA7 And Win64 Then Type PRINTER_INFO_1 flags As LongPtr pPDescription As LongPtr pName As LongPtr pComment As LongPtr #Else Type PRINTER_INFO_1 flags As Long pPDescription As Long pName As Long pComment As Long End Type #End If Private Const PRINTER_ENUM_LOCAL = &H2 #If VBA7 And Win64 Then Private Declare PtrSafe Function Enumprinters Lib "WINSPOOL.DRV" Alias "EnumPrintersA" _ (ByVal flags As LongPtr, ByVal Name As String, ByVal Level As LongPtr, pPrinterEnum As Any, _ ByVal cdBuf As LongPtr, pcbNeeded As LongPtr, pcReturned As LongPtr) As Long Private Declare PtrSafe Sub MoveMemory Lib "KERNEL32" Alias "RtlMoveMemory" _ (Dest As Any, Source As Any, ByVal length&) #Else Private Declare Function Enumprinters Lib "WINSPOOL.DRV" Alias "EnumPrintersA" _ (ByVal flags As Long, ByVal Name As String, ByVal Level As Long, pPrinterEnum As Any, _ ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long Private Declare Sub MoveMemory Lib "KERNEL32" Alias "RtlMoveMemory" _ (Dest As Any, Source As Any, ByVal length&) #End If

  • 「&HFFFF」「&H1A」とは?

    はじめまして。 vb6.0の開発をしている者です。 表題にもありますように、「&HFFFF」「&H1A」は何を指しているのでしょうか? 実際は以下のように記述しています。 l = SendMessage("&HFFFF", "&H1A", 0, "windows") Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lparam As String) As Long 初歩的な質問で申し訳ないのですが、なかなかこれだ!という情報を見つけれずにいます。よろしくお願いします。

  • エクセル2010 VBAのサウンドの宣言

    エクセル2007でVBAをプログラミングして使っています。 2010で同じVBAを走らすと Public Declare Function apisndPlaySound Lib "WINMM" Alias "sndPlaySoundA" _ (ByVal FileName As String, ByVal SND_ASYNC As Long) As Long とSOUNDの記述の宣言の Function のところで強調表示が出てエラーになります。 2007、2003等ではエラーは出ず使えたのですが、書き換える必要があるようです。 前に進めず困っています。どなたかご教授をよろしくお願いします。

  • VBAでIEの「ファイルのダウンロード」ダイアログを制御

    VBではなくVBAにて、IEの「ファイルのダウンロード」ダイアログを制御したいと思い、過去の同様の質問等を参考に下記のソースを作成して動かしてみましたが、「ファイルのダウンロード」画面で、「保存(S)」ボタンのハンドルを取得するところまではできましたが、sendMessageでクリックができず、次に進むことが出来ませんでした。 手動で「保存(S)」ボタンを押下して、強制的に「名前を付けて保存」画面に遷移させた後プログラムを再開すると、同画面の「保存(S)」ボタンのクリックはできました。 同じロジックで「名前を付けて保存」画面の「保存(S)」は動くのに、「ファイルのダウンロード」画面の「保存(S)」が動かないのはなぜでしょうか。 どなたかおわかりになる方がいらっしゃいましたら、ご回答をお願いします。 ***使用環境*** OS: XP pro IE: 6 OFFICE:2002 ***以下作成したソース(エラー制御は省略)*** Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long Private Sub Test() Dim ret1 As Long Dim ret2 As Long Const WM_COMMAND As Long = &H111 ret1 = FindWindow("#32770", "ファイルのダウンロード") ret2 = FindWindowEx(ret1, 0, "Button", "保存(&S)") Call SendMessage(ret1, WM_COMMAND, GetDlgCtrlID(ret2), ByVal ret2) ret1 = FindWindow("#32770", "名前を付けて保存") ret2 = FindWindowEx(ret1, 0, "Button", "保存(&S)") Call SendMessage(ret1, WM_COMMAND, GetDlgCtrlID(ret2), ByVal ret2) End Sub ***以上ソース終わり***

専門家に質問してみよう