Archive for 4月, 2012

  1. 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   
    ---------------------------
  2. 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   
    ---------------------------
  3. 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   
    ---------------------------
  4. 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   
    ---------------------------
  5. 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   
    ---------------------------
  6. 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   
    ---------------------------
  7. Hello, Win32 API(C++/CLI) World!

    Posted on 4月 15th, 2012 by cx20

    Win32 API(C++/CLI)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は C++/CLI からの呼出し例である。

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        MessageBox( NULL, _T("Hello, Win32 API(C++/CLI) World!"), _T("Hello, World!"), MB_OK );
        return 0;
    }

    コンパイル方法(Visual C++)

    C:¥> cl hello.cpp /clr /link user32.lib

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(C++/CLI) World!
    ---------------------------
    OK   
    ---------------------------
  8. Hello, Win32 API(C++) World!

    Posted on 4月 14th, 2012 by cx20

    Win32 API(C++)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は C++ からの呼出し例である。

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        MessageBox( NULL, _T("Hello, Win32 API(C++) World!"), _T("Hello, World!"), MB_OK );
        return 0;
    }

    コンパイル方法(Visual C++)

    C:¥> cl hello.cpp /link user32.lib

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(C++) World!
    ---------------------------
    OK   
    ---------------------------
  9. Hello, Win32 API(C言語) World!

    Posted on 4月 13th, 2012 by cx20

    Win32 API(C言語)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は C言語 からの呼出し例である。

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        MessageBox( NULL, _T("Hello, Win32 API World!"), _T("Hello, World!"), MB_OK );
        return 0;
    }

    コンパイル方法(Visual C++)

    C:¥> cl hello.c /link user32.lib

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API World!
    ---------------------------
    OK   
    ---------------------------
  10. Hello, Win32 API(GUI) World!

    Posted on 4月 12th, 2012 by cx20

    Win32 API(GUI)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    {
        MessageBox( NULL, _T("Hello, Win32 API(GUI) World!"), _T("Hello, World!"), MB_OK );
        return 0;
    }

    コンパイル方法(Visual C++)

    C:¥> cl hello.c /link user32.lib /SUBSYSTEM:WINDOWS

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(GUI) World!
    ---------------------------
    OK   
    ---------------------------