Windows常用的经典代码(一)

一:IME無効(スレッドのIME自体を消し去る)

BOOL DisableIME()
{
    HMODULE himm32 = NULL;
    BOOL ( WINAPI *lpfImmDisableIME )( DWORD );
    
    himm32 = LoadLibrary( _T("imm32.dll") );    // ライブラリの呼び出し
    if ( !himm32 ) return FALSE;
    
    lpfImmDisableIME = ( BOOL ( WINAPI* )( DWORD ) )(
                GetProcAddress( himm32, "ImmDisableIME" ) );
    if ( lpfImmDisableIME )
    {
        lpfImmDisableIME(0);                    // ImmDisableIMEの実行
        FreeLibrary( himm32 );
        return TRUE;
    }
    FreeLibrary( himm32 );
    return FALSE;
}
imm32.dllを動的にリンクして実行します。IMEを開放しただけで不要なメモリを節約出来るので、全角入力を使わないスレッド内全てに有効です。また、返り値は関数の成功/失敗になります。


二:ターゲットウインドウの実行ファイル名を取得

BOOL GetModuleBaseNameFromHWnd( __in HWND hWnd, __out LPTSTR lpszBuf, DWORD dwSize )
{
    HMODULE    hpsapi = NULL;
#ifdef _UNICODE
    DWORD ( WINAPI *lpfGetModuleBaseName )( HANDLE, HMODULE, LPCWSTR, DWORD );
#else    // ANSI
    DWORD ( WINAPI *lpfGetModuleBaseName )( HANDLE, HMODULE, LPCSTR, DWORD );
#endif    //_UNICODE
    BOOL ( WINAPI *lpfEnumProcessModules )( HANDLE, HMODULE*, DWORD, LPDWORD );

    hpsapi = LoadLibrary( _T("Psapi.dll") );        // ライブラリの呼び出し
    if ( !hpsapi ) return FALSE;

#ifdef _UNICODE
    lpfGetModuleBaseName = ( DWORD ( WINAPI* ) ( HANDLE, HMODULE, LPCWSTR, DWORD ) )
                    GetProcAddress( hpsapi, "GetModuleBaseNameW" );
#else    // ANSI
    lpfGetModuleBaseName = ( DWORD ( WINAPI* )( HANDLE, HMODULE, LPCSTR, DWORD ) )
                    GetProcAddress( hpsapi, "GetModuleBaseNameA" );
#endif    //_UNICODE
    lpfEnumProcessModules = ( BOOL ( WINAPI* )( HANDLE, HMODULE*, DWORD, LPDWORD ) )
                    GetProcAddress( hpsapi, "EnumProcessModules" );

    if ( ( lpfGetModuleBaseName ) || ( lpfEnumProcessModules ) )
    {

        DWORD dwPID;
        HANDLE hProcess;

        GetWindowThreadProcessId( hWnd, &dwPID );
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID );
        if ( hProcess )
        {
            HMODULE hModule;
            DWORD cbReturned;
            if ( lpfEnumProcessModules( hProcess, &hModule, sizeof( hModule ), &cbReturned ) )
            {
                //ファイル名のみGetModuleBaseName フルパスGetModuleFileNameEx
                lpfGetModuleBaseName( hProcess, hModule, lpszBuf, dwSize );
                FreeLibrary( hpsapi );
                return TRUE;
            }
        }
    }
    FreeLibrary( hpsapi );
    return FALSE;
}

Psapi.libを動的にリンクして実行します。返り値は関数の成功/失敗になり、結果の文字列は第2引数に指定したバッファに返ります。また、GetModuleBaseName()をGetModuleFileNameEx()に変更することでフルパスの取得が可能になります。


三:アプリが64bitかどうか判別

BOOL Is64bitProcess( __in HWND hWnd, __out LPBOOL is64bits )
{
    // IsWow64Process関数が存在するOSか判別
    if ( GetProcAddress ( GetModuleHandle( _T("kernel32.dll") ), "IsWow64Process" ) )
    {
        SYSTEM_INFO si;
        GetNativeSystemInfo(&si);

        // OSのアーキテクチャがx64ならWOW64か判別
        if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
        {
            DWORD dwPID;
            HANDLE hProcess;
            GetWindowThreadProcessId( hWnd, &dwPID );
            if ( !dwPID )
                return FALSE;

            hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID );
            if ( !hProcess ) return FALSE;
            IsWow64Process( hProcess, is64bits );
            CloseHandle( hProcess );
            *is64bits = !( *is64bits );
        }
        // OSのアーキテクチャがx86
        else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
        *is64bits = FALSE;
    }
    else
        *is64bits = FALSE;
    return TRUE;
}
返り値は関数の成功/失敗(プロセスが存在しないなど)になり、結果はis64bitsに返ります。本当は返り値として0、32、64を返すほうがいいんじゃないかと思いますが。


四:GUID>文字列変換

static VOID r_xtoad( UINT n, INT d, __out LPSTR buf )  // 終端を返さない
{
    do
    {
        d--;
        buf[ d ] = ( n & 0xF ) + '0';
        if ( buf[ d ] > '9' )
            buf[ d ] += 7;
    }
    while ( n >>= 4 );
    while ( d-- ) buf[ d ] = '0';
}

VOID r_StringFromCLSID( GUID rclsid, __out LPSTR buf )
{
    int i = 0;

    buf[ 0 ] = '{';
    r_xtoad( rclsid.Data1, 8, &buf[ 1 ] );
    buf[ 9 ] = '-';
    r_xtoad( rclsid.Data2, 4, &buf[ 10 ] );
    buf[ 14 ] = '-';
    r_xtoad( rclsid.Data3, 4, &buf[ 15 ] );
    buf[ 19 ] = '-';
    r_xtoad( rclsid.Data4[ 0 ], 2, &buf[ 20 ] );
    r_xtoad( rclsid.Data4[ 1 ], 2, &buf[ 22 ] );
    buf[ 24 ] = '-';
    for (; i < 6 ; i++ )
        r_xtoad( rclsid.Data4[ 2 + i ], 2, &buf[ 25 + i * 2 ] );
    buf[ 37 ] = '}';
    buf[ 38 ] = '\0';
}
r_StringFromCLSID()はole32.dllのStringFromCLSID()を自前で実装したものです。
StringFromCLSID()を使う場合はダブルポインタでUNICODEという都合の悪い文字列の宣言とモジュールのリンクが必要になるので、自前で変換することにしました。
数値を16進数と考えてブロック単位で文字列化するだけですから簡単です。純正より何倍か速いですが、使い道はそれほどないでしょう。

你可能感兴趣的:(mfc)