Archive for the ‘Win32 API’ Category
-
Hello, Win32 API(F#) World!
Posted on 4月 25th, 2012 by cx20
Win32 API(F#)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は F# にて DllImport 属性を用いた呼出し例である。ソースコード
open System open System.Runtime.InteropServices [<DllImport("user32.dll")>] extern int MessageBox( UInt32 hWnd, String lpText, String lpCaption, UInt32 uType) let x = MessageBox( 0u, "Hello, Win32 API(F#) World!", "Hello, World!", 0u )
コンパイル方法
C:¥> fsc Hello.fs
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(F#) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(VB.NET) World!
Posted on 4月 24th, 2012 by cx20
Win32 API(VB.NET)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は VB.NET にて Declare ステートメントを用いた呼出し例である。ソースコード
Imports System Imports System.Runtime.InteropServices Module Hello Declare Auto Function MessageBox Lib "user32.dll" Alias "MessageBox" ( _ ByVal hWnd As IntPtr, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal nType As UInteger _ ) As Integer Sub Main() MessageBox( New IntPtr(0), "Hello, Win32 API(VB.NET) World!", "Hello, World!", 0 ) End Sub End Module
「文字セット」に「Auto」を指定した場合は「エイリアス名」「プラットフォーム」に応じて、呼び出される API 関数名が自動判別される。
「文字セット」に「Ansi」もしくは「Unicode」を指定した場合は「エイリアス名」が API 関数名として使用される為、”A” / “W” のどちらのバージョンであるか明示的に指定する必要がある。(指定を行わない場合、関数名が見つからずエラーとなる)文字セット指定 エイリアス名 プラットフォーム 文字変換 判別 API関数名 Auto MessageBox Windows 9x系 ANSI “A” MessageBoxA Auto MessageBox Windows NT系 Unicode “W” MessageBoxW Ansi または 省略 MessageBox – ANSI – Not Found Ansi または 省略 MessageBoxA – ANSI – MessageBoxA Unicode MessageBox – Unicode – Not Found Unicode MessageBoxW – Unicode – MessageBoxW また、Win32 データ型と VB.NET データ型の対応は主に以下のようになっている。「(2.0)」は、.NET Framework 2.0 で追加された型を示す。文字関連の型に関しては文字セット指定が必要なことに注意。
Win32 データ型 C/C++ データ型 .NET データ型 VB.NET データ型 HANDLE void * IntPtr – BYTE unsigned char Byte Byte SHORT short Int16 Short WORD unsigned short UInt16 UShort (2.0) INT int Int32 Integer UINT unsigned int UInt32 UInteger (2.0) LONG long Int32 Integer BOOL int Int32 Integer DWORD unsigned long UInt32 UInteger (2.0) ULONG unsigned long UInt32 UInteger (2.0) CHAR char Char (Ansi) Char (Ansi) WCHAR wchar_t Char (Unicode) Char (Unicode) LPSTR char * StringBuilder (Ansi) – LPCSTR const char * String (Ansi) String (Ansi) LPWSTR wchar_t * StringBuilder (Unicode) – LPCWSTR const wchar_t * String (Unicode) String (Unicode) FLOAT float Single Single DOUBLE double Double Double コンパイル方法
C:¥> vbc Hello.vb
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(VB.NET) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(C#) World!
Posted on 4月 23rd, 2012 by cx20
Win32 API(C#)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は C# にて DllImport 属性を用いた呼出し例である。ソースコード
using System; using System.Runtime.InteropServices; class Hello { [DllImport("user32.dll", CharSet=CharSet.Auto)] private extern static uint MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType); static void Main(string[] args) { MessageBox( new IntPtr(0), "Hello, Win32 API(C#) World!", "Hello, World!", 0 ); } }
「文字セット」に「Auto」を指定した場合は「関数定義」「プラットフォーム」に応じて、呼び出される API 関数名が自動判別される。
「文字セット」に「Ansi」もしくは「Unicode」を指定した場合それぞれ、末尾が “A” / “W” の API 関数名として自動判別される。文字セット指定 関数定義 プラットフォーム 文字変換 判別 API関数名 Auto MessageBox Windows 9x系 ANSI “A” MessageBoxA Auto MessageBox Windows NT系 Unicode “W” MessageBoxW Ansi または 省略 MessageBox – ANSI “A” MessageBoxA Ansi または 省略 MessageBoxA – ANSI – MessageBoxA Unicode MessageBox – Unicode “W” MessageBoxW Unicode MessageBoxW – Unicode – MessageBoxW また、Win32 データ型と C# データ型の対応は主に以下のようになっている。文字関連の型に関しては文字セット指定が必要なことに注意。
Win32 データ型 C/C++ データ型 .NET データ型 C# データ型 HANDLE void * IntPtr – BYTE unsigned char Byte byte SHORT short Int16 short WORD unsigned short UInt16 ushort INT int Int32 int UINT unsigned int UInt32 uint LONG long Int32 int BOOL int Int32 int DWORD unsigned long UInt32 uint ULONG unsigned long UInt32 uint CHAR char Char (Ansi) char (Ansi) WCHAR wchar_t Char (Unicode) char (Unicode) LPSTR char * StringBuilder (Ansi) – LPCSTR const char * String (Ansi) string (Ansi) LPWSTR wchar_t * StringBuilder (Unicode) – LPCWSTR const wchar_t * String (Unicode) string (Unicode) FLOAT float Single float DOUBLE double Double double コンパイル方法
C:¥> csc Hello.cs
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(C#) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(PowerShell) World!
Posted on 4月 22nd, 2012 by cx20
Win32 API(PowerShell)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は PowerShell での P/Invoke による呼出し例である。ソースコード
function Main { MessageBox 0 "Hello, Win32 API(PowerShell)!" "Hello, World!" 0 } ## Invoke a Win32 P/Invoke call. ## http://www.leeholmes.com/blog/2006/07/21/get-the-owner-of-a-process-in-powershell-%e2%80%93-pinvoke-and-refout-parameters/ function Invoke-Win32([string] $dllName, [Type] $returnType, [string] $methodName, [Type[]] $parameterTypes, [Object[]] $parameters) { ## Begin to build the dynamic assembly $domain = [AppDomain]::CurrentDomain $name = New-Object Reflection.AssemblyName 'PInvokeAssembly' $assembly = $domain.DefineDynamicAssembly($name, 'Run') $module = $assembly.DefineDynamicModule('PInvokeModule') $type = $module.DefineType('PInvokeType', "Public,BeforeFieldInit") ## Define the actual P/Invoke method $method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl', $returnType, $parameterTypes) ## Apply the P/Invoke constructor $ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string]) $attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName $method.SetCustomAttribute($attr) ## Create the temporary type, and invoke the method. $realType = $type.CreateType() $realType.InvokeMember($methodName, 'Public,Static,InvokeMethod', $null, $null, $parameters) } function MessageBox([Int32] $hWnd, [String] $lpText, [String] $lpCaption, [Int32] $uType) { $parameterTypes = [Int32], [String], [String], [Int32] $parameters = $hWnd, $lpText, $lpCaption, $uType Invoke-Win32 "user32.dll" ([Int32]) "MessageBoxA" $parameterTypes $parameters } . Main
実行方法
C:¥> PowerShell -file hello.ps1
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(PowerShell) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(JScript) World!
Posted on 4月 21st, 2012 by cx20
Win32 API(JScript)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
JScript には Win32 API を直接呼び出す機能は存在しないが、他のコンポーネントを経由することで、呼び出すことが可能である。
Win32 API を呼び出すことが可能なコンポーネントとしては「DynamicWrapper」「SFC mini」「Excel」等がある。
以下は DynamicWrapper を経由した Win32 API 呼出し例である。ソースコード(JScript + COM + DynamicWrapper + Win32 API)
main(); function main() { var win32 = new ActiveXObject("DynamicWrapper"); win32.Register( "user32.dll", "MessageBoxA", "i=hssu", "f=s", "r=l" ); win32.MessageBoxA( 0, "Hello, Win32 API(JScript) World!", "Hello, World!", 0 ); }
以下は SFC mini を経由した Win32 API 呼出し例である。
ソースコード(JScript + COM + SFC miin + Win32 API)
main(); function main() { var messageBox = new ActiveXObject("SfcMini.DynaCall"); messageBox.Declare( "user32", "MessageBoxA" ); messageBox( 0, "Hello, Win32 API(JScript) World!", "Hello, World!", 0 ); }
以下は Excel を経由した Win32 API 呼出し例である。実際には、Excel の「Call 関数」を ExecuteExcel4Macro メソッド経由で呼び出す例となっている。
ソースコード(JScript + COM + Excel + Call 関数 + Win32 API)
main(); function main() { var excel = new ActiveXObject("Excel.Application"); var strMacro = 'CALL("user32", "MessageBoxA", "JJCCJ", 0,"Hello, Win32 API(JScript) World!", "Hello, World!", 0)' excel.ExecuteExcel4Macro( strMacro ); }
実行方法
C:¥> CSciprt hello.js
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(JScript) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(VBScript) World!
Posted on 4月 20th, 2012 by cx20
Win32 API(VBScript)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。VBScript には Win32 API を直接呼び出す機能は存在しないが、他のコンポーネントを経由することで、呼び出すことが可能である。
Win32 API を呼び出すことが可能なコンポーネントとしては「DynamicWrapper」「SFC mini」「Excel」等がある。
以下は DynamicWrapper を経由した Win32 API 呼出し例である。ソースコード(VBScript + COM + DynamicWrapper + Win32 API)
Option Explicit Call Main() Sub Main() Dim win32 Set win32 = CreateObject("DynamicWrapper") win32.Register "user32.dll", "MessageBoxA", "i=hssu", "f=s", "r=l" win32.MessageBoxA Null, "Hello, Win32 API(VBScript) World!", "Hello, World!", 0 End Sub
以下は SFC mini を経由した Win32 API 呼出し例である。
ソースコード(VBScript + COM + SFC mini + Win32 API)
Option Explicit Call Main() Sub Main() Dim MessageBox Set MessageBox = CreateObject("SfcMini.DynaCall") MessageBox.Declare "user32", "MessageBoxA" MessageBox 0, "Hello, Win32 API(VBScript) World!", "Hello, World!", vbOkOnly End Sub
以下は Excel を経由した Win32 API 呼出し例である。実際には、Excel の「Call 関数」を ExecuteExcel4Macro メソッド経由で呼び出す例となっている。
ソースコード(VBScript + COM + Excel + Call 関数 + Win32 API)
Option Explicit Call Main() Sub Main() Dim excel Set excel = CreateObject("Excel.Application") Dim strMacro strMacro = "CALL('user32', 'MessageBoxA', 'JJCCJ', 0, 'Hello, Win32 API(VBScript) World!', 'Hello, World!', 0)" strMacro = Replace( strMacro, "'", """" ) excel.ExecuteExcel4Macro( strMacro ) End Sub
なお、Call 関数で使用している、”JJCCJ” のコード値は MessageBoxA 関数の戻り値ならびに各引数のデータ型に対応している。詳細は「CALL 関数と REGISTER 関数の使い方」を参照のこと。
コード 説明 渡す方法 C 言語での宣言 A 論理値 (FALSE = 0、TRUE = 1) 値 short int B IEEE 8 バイト浮動小数点数 値 (Windows)
参照 (Macintosh)double (Windows)
double * (Macintosh)C 末尾が Null の文字列 (最大文字列長 = 255) 参照 char * D バイト数を含む文字列 (先頭バイトが文字列の長さ、最大文字列長 = 255) 参照 unsigned char * E IEEE 8 バイト浮動小数点数 参照 double * F 末尾が Null の文字列 (最大文字列長 = 255) 参照 (指定した引数の変更) char * G バイト数を含む文字列 (先頭バイトが文字列の長さ、最大文字列長 = 255) 参照 (指定した引数の変更) unsigned char * H 符号なし 2 バイト整数 値 unsigned short int I 符号付き 2 バイト整数 値 short int J 符号付き 4 バイト整数 値 long int K 配列 参照 FP * L 論理値 (FALSE = 0、TRUE = 1) 参照 short int * M 符号付き 2 バイト整数 参照 short int * N 符号付き 4 バイト整数 参照 long int * O 配列 参照 引数は次の 3 種類
unsigned short int *
unsigned short int *
double [ ]P Excel の OPER データ構造体 参照 OPER * R Excel の XLOPER データ構造体 参照 XLOPER * 実行方法
C:¥> CSciprt hello.vbs
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(VBScript) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(VBA) World!
Posted on 4月 19th, 2012 by cx20
Win32 API(VBA)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は VBA(Microsoft Visual Basic for Applications)からの呼出し例である。ソースコード(Excel VBA / 32bit版)
Declare Function MessageBox Lib "User32.dll" Alias "MessageBoxA" ( _ ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Long _ ) As Integer Sub Main() MessageBox 0, "Hello, Win32 API(VBA) World!", "Hello, World!", vbOKOnly End Sub
64bit 版 VBA では Win32 API 使用時に PtrSafe を指定する必要がある。
ソースコード(Excel VBA / 64bit版)
Declare PtrSafe Function MessageBox Lib "User32.dll" Alias "MessageBoxA" ( _ ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Long _ ) As Integer Sub Main() MessageBox 0, "Hello, Win32 API(VBA) World!", "Hello, World!", vbOKOnly End Sub
なお、PtrSfae 属性は Office 2010 からの機能である為、下位互換の為に以下の条件付きコンパイル属性を指定することが推奨されている。
ソースコード(Excel VBA / 互換性を考慮した記述)
#If VBA7 And Win64 Then Declare PtrSafe Function MessageBox Lib "User32.dll" Alias "MessageBoxA" ( _ ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Long _ ) As Integer #else Declare Function MessageBox Lib "User32.dll" Alias "MessageBoxA" ( _ ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Long _ ) As Integer #end if Sub Main() MessageBox 0, "Hello, Win32 API(VBA) World!", "Hello, World!", vbOKOnly End Sub
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(VBA) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(VB6) World!
Posted on 4月 18th, 2012 by cx20
Win32 API(VB6)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は VB6 からの呼出し例である。ソースコード
Declare Function MessageBox Lib "User32.dll" Alias "MessageBoxA" ( _ ByVal hWnd As Long, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Long _ ) As Integer Sub Main() MessageBox 0, "Hello, Win32 API(VB6) World!", "Hello, World!", vbOKOnly End Sub
Win32 データ型と VB6 データ型の対応は主に以下のようになっている。
Win32 データ型 C/C++ データ型 VB6 HANDLE void * Long BYTE unsigned char Byte SHORT short Integer WORD unsigned short Integer INT int Long UINT unsigned int Long LONG long Long BOOL int Long DWORD unsigned long Long ULONG unsigned long Long CHAR char Byte WCHAR wchar_t Integer LPSTR char * String LPCSTR const char * String LPWSTR wchar_t * Long (StrPtr) LPCWSTR const wchar_t * Long (StrPtr) FLOAT float Single DOUBLE double Double コンパイル方法
C:¥> vb6 /make hello.vbp
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(VB6) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(MASM) World!
Posted on 4月 17th, 2012 by cx20
Win32 API(MASM)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は MASM からの呼出し例である。ソースコード(MASM)
; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762 TITLE hello.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG77810 DB 'Hello, World!', 00H ORG $+2 $SG77811 DB 'Hello, Win32 API(MASM) World!', 00H _DATA ENDS PUBLIC _main EXTRN __imp__MessageBoxA@16:PROC ; Function compile flags: /Odtp _TEXT SEGMENT _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; File hello.c ; Line 4 push ebp mov ebp, esp ; Line 5 push 0 push OFFSET $SG77810 push OFFSET $SG77811 push 0 call DWORD PTR __imp__MessageBoxA@16 ; Line 6 xor eax, eax ; Line 7 pop ebp ret 0 _main ENDP _TEXT ENDS END
上記コードは、下記の C のソースを「cl hello.c /FA」にてアセンブラ出力したものである。
ソースコード(C言語)
#include <windows.h> int main( int argc, char* argv[] ) { MessageBoxA( NULL, "Hello, Win32 API(MASM) World!", "Hello, World!", MB_OK ); return 0; }
コンパイル方法(Visual C++)
C:¥> ml hello.asm C:¥> link hello.obj user32.lib
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(MASM) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(DLL) World!
Posted on 4月 16th, 2012 by cx20
Win32 API(DLL)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
Win32 API は DLL として提供されており、ライブラリのリンク方法としては、インポートライブラリを使用した「暗黙的リンク」と LoadLibrary() による「明示的リンク」の2つの方法がある。
ここでは C言語による LoadLibrary() を用いた DLL の呼出しの例(明示的リンク)を記載する。ソースコード
#include <windows.h> #include <tchar.h> #ifdef UNICODE typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCWSTR, LPCWSTR, UINT); #else typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT); #endif int _tmain( int argc, TCHAR* argv[] ) { HINSTANCE hInstance = LoadLibrary( _T("user32.dll") ); #ifdef UNICODE PROC pfunc = GetProcAddress( hInstance, "MessageBoxW" ); #else PROC pfunc = GetProcAddress( hInstance, "MessageBoxA" ); #endif ((PFNMESSAGEBOX)pfunc)( NULL, _T("Hello, Win32 API(DLL) World!"), _T("Hello, World!"), MB_OK ); return 0; }
Win32 API は内部的に UNICODE 版(例:MessageBoxW)と ANSI 版(例:MessageBoxA)の2つのバージョンをもっており、GetProcAddress() による呼出しの場合は、UNICODE/ANSI どちらの関数であるか指定する必要がある。
Win32 API のプロトタイプ宣言(参考)
WINUSERAPI int WINAPI MessageBoxA( __in_opt HWND hWnd, __in_opt LPCSTR lpText, __in_opt LPCSTR lpCaption, __in UINT uType); WINUSERAPI int WINAPI MessageBoxW( __in_opt HWND hWnd, __in_opt LPCWSTR lpText, __in_opt LPCWSTR lpCaption, __in UINT uType); #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE
コンパイル方法(Visual C++ / UNICODE ビルド)
C:¥> cl hello.c /DUNICODE /D_UNICODE
上記の「/D」オプションで指定している定義「UNICODE」は Win32 API 用、「_UNICODE」は、C ランタイム用の定義となっている。
コンパイル方法(Visual C++ / ANSI ビルド)
C:¥> cl hello.c
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(DLL) World! --------------------------- OK ---------------------------