Frost Moon Project

Src/Nelumbo.cpp - Nelumbo Ver.1.72 - Frost Moon Project   アクセスランキング  

Home > ソフトウェア > Nelumbo > Nelumbo172.zip > Src > Nelumbo.cpp

 
//Nelumbo.cpp
//メイン

/*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
    Nelumbo Ver.1.72
    Coded by x@rgs

    This code is released under NYSL Version 0.9982
    See NYSL_withfaq.TXT for further details.

    Nelumboはクリックひとつでパスワード「*****」を表示&コピーするソフトウェアです。
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*/

#include"StdAfx.h"
#include"CommonSettings.h"
#include"Function.h"
#include"PrivateProfile.h"
#include"Settings.h"
#include"resources/resource.h"

#define ID_TRAYMENU 10001

//タスクトレイ用メッセージ
UINT MSG_TRAYMENU;
//タスクバー再作成用メッセージ
UINT MSG_TASKBARCREATED;

HWND g_hwndMain=NULL;
HINSTANCE g_hInstance=NULL;


struct CONFIG g_Config;

//マウスフックハンドル
HHOOK g_hkMouseHook;
//キーボードフックハンドル
HHOOK g_hkKeyboardHook;

//マウスフック用DLL
HMODULE g_hHookDll;
typedef BOOL(*INSTALLMSGHOOK_PTR)(const DWORD);
typedef BOOL(*CALLGETPASSWORD_PTR)(const HWND,const HWND);
typedef BOOL(*CALLSHOWPASSWORD_PTR)(const HWND,const HWND);
typedef BOOL(*UNINSTALLMSGHOOK_PTR)();
typedef BOOL(*INSTALLFOCUSHOOK_PTR)(HWND,UINT);
typedef BOOL(*UNINSTALLFOCUSHOOK_PTR)();
INSTALLMSGHOOK_PTR pInstallMsgHook;
CALLGETPASSWORD_PTR pCallGetPassword;
CALLSHOWPASSWORD_PTR pCallShowPassword;
UNINSTALLMSGHOOK_PTR pUninstallMsgHook;
INSTALLFOCUSHOOK_PTR pInstallFocusHook;
UNINSTALLFOCUSHOOK_PTR pUninstallFocusHook;


UINT WM_HOOKDIALOG;


//ターゲットのハンドル
HWND g_hwndTarget;
//ターゲットの座標
RECT g_rcTarget={-1,-1,-1,-1};


//機能を無効にする
bool g_bDisable;
//設定ダイアログが表示されている
bool g_bSettingsDialog;

bool g_bWorking;


//マウスやキーボードの状態フラグ
//Ctrlキーが押されている
#define CTRLKEYDOWN 1<<0
//Altキーが押されている
#define ALTKEYDOWN 1<<1
//左クリックされている
#define LBUTTONDOWN 1<<2
//右クリックされている
#define RBUTTONDOWN 1<<3
//状態
DWORD g_dwState;

HICON g_hTrayIcon;
HICON g_hDisableTrayIcon;


//処理終了メッセージ(Thread->Main)
//GetPasswordThread()
#define WM_EXIT_GETPASSWORD_THREAD (WM_APP+5)

const TCHAR* const g_szEvent=_T("{5F5D8ED4-0C2F-4ffd-A89D-6CF2006C3A9A}");

//GetPasswordThread()の引数
typedef struct{
    //処理終了の報告先ウインドウハンドル
    HWND hWnd;
    //パスワード取得に成功した場合、ターゲットのハンドルが代入される
    HWND* phwndResult;
    //ターゲットの座標
    RECT* prcTarget;
    //動作の設定
    DWORD dwKeyData[9];
    //現在のキーボードやマウスの状態
    KEYDATA eKeyData;
}GETPASSWORDTHREADPARAMS,*LPGETPASSWORDTHREADPARAMS;

//パスワードを取得するスレッドのハンドル
HANDLE g_hGetPasswordThread;

//EnumChildEditProc()の引数
typedef struct{
    //パスワードを取得したかどうか
    bool* pbResult;
    LPGETPASSWORDTHREADPARAMS lpparam_GetPasswordThread;
}ENUMCHILDEDITPROCPARAMS,*LPENUMCHILDEDITPROCPARAMS;

//EnumWindowsProc()の引数
typedef struct{
    BOOL (CALLBACK*pEnumChildWindowsProc)(HWND,LPARAM);
    LPARAM lParam;
}PARAM_ENUMWINDOWSPROC,*LPPARAM_ENUMWINDOWSPROC;

//クリティカルセクション
CRITICAL_SECTION g_CriticalSection;


//タスクトレイ登録/削除
void TaskTrayIcon(HWND hWnd,DWORD dwMessage,bool bEnable=true){
    NOTIFYICONDATA NotifyIconData={sizeof(NOTIFYICONDATA),hWnd,ID_TRAYMENU,NIF_MESSAGE|NIF_ICON|NIF_TIP,MSG_TRAYMENU,(bEnable)?g_hTrayIcon:g_hDisableTrayIcon};

    //ツールチップ
    lstrcpy(NotifyIconData.szTip,NELUMBO_VERSION);

//  while(1){
    for(int i=0;i<10;i++){
        if(Shell_NotifyIcon(dwMessage,&NotifyIconData)){
            return;
        }else{
            if(GetLastError()!=ERROR_TIMEOUT){
                if(dwMessage!=NIM_DELETE){
//                  MessageBox(NULL,_T("アイコンの登録に失敗しました。"),NELUMBO_VERSION,MB_OK|MB_ICONEXCLAMATION|MB_ICONEXCLAMATION);
//                  SendMessage(hWnd,WM_CLOSE,(WPARAM)0,(LPARAM)0);
//                  return;
                }
            }
            if(Shell_NotifyIcon(NIM_MODIFY,&NotifyIconData)){
                return;
            }else{
                Sleep(1000);
            }
        }
    }
    return;
}

//WH_GETMESSAGEフックをインストール
bool InstallMsgHook(DWORD dwThreadId){
    if(g_hHookDll==NULL){
        g_hHookDll=LoadLibrary(_T("MsgHook.dll"));

        pInstallMsgHook=(INSTALLMSGHOOK_PTR)GetProcAddress(g_hHookDll,"InstallMsgHook");
        pCallGetPassword=(CALLGETPASSWORD_PTR)GetProcAddress(g_hHookDll,"CallGetPassword");
        pCallShowPassword=(CALLSHOWPASSWORD_PTR)GetProcAddress(g_hHookDll,"CallShowPassword");
        pUninstallMsgHook=(UNINSTALLMSGHOOK_PTR)GetProcAddress(g_hHookDll,"UninstallMsgHook");
    }

    if(g_hHookDll!=NULL){
        if(pInstallMsgHook)pInstallMsgHook(dwThreadId);
    }
    return g_hHookDll!=NULL;
}

//WH_GETMESSAGEフックをアンインストール
bool UninstallMsgHook(){
    bool bResult=false;

    if(g_hHookDll){
        if(pUninstallMsgHook)pUninstallMsgHook();
    }
    return bResult;
}

//パスワードマスクを解除する
bool UnmaskPassword(HWND* phwndResult,HWND hWnd,bool bShowPassword){
    DWORD dwProcessId=0;
    DWORD dwThreadId=GetWindowThreadProcessId(hWnd,&dwProcessId);

    if(dwThreadId){
        //OSが64bitか
        BOOL b64Bit=TRUE;
        TCHAR szSystemWow64Directory[MAX_PATH]={};
        typedef UINT(WINAPI*GETSYSTEMWOW64DIRECTORYW)(LPTSTR,UINT);
        GETSYSTEMWOW64DIRECTORYW GetSystemWow64DirectoryW=(GETSYSTEMWOW64DIRECTORYW)GetProcAddress(GetModuleHandle(_T("kernel32")),"GetSystemWow64DirectoryW");

        if(GetSystemWow64DirectoryW==NULL){
            b64Bit=FALSE;
        }else if(GetSystemWow64DirectoryW(szSystemWow64Directory,ARRAY_SIZEOF(szSystemWow64Directory))==0&&
                 (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)){
            b64Bit=FALSE;
        }

        //Wow64で動作しているか
        HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,dwProcessId);
        BOOL bWow64=FALSE;
        typedef BOOL(WINAPI*ISWOW64PROCESS)(HANDLE,PBOOL);
        ISWOW64PROCESS IsWow64Process=(ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")),"IsWow64Process");
        if(IsWow64Process!=NULL){
            IsWow64Process(hProcess,&bWow64);
        }
        CloseHandle(hProcess);

        if(b64Bit&&!bWow64){
            //環境変数NELUMBO_TARGET_HWNDに対象のウインドウハンドルを代入
            TCHAR szEnv[32]={};

            wsprintf(szEnv,_T("%d"),hWnd);
            SetEnvironmentVariable(_T("NELUMBO_TARGET_HWND"),szEnv);

            if(bShowPassword){
                SetEnvironmentVariable(_T("NELUMBO_SHOW_PASSWORD"),_T("DUMMY"));
            }

            //先に代入
            *(phwndResult)=hWnd;

            TCHAR szProcess[]=_T("Nelumbo64");
            STARTUPINFO StartupInfo={sizeof(STARTUPINFO)};
            PROCESS_INFORMATION ProcessInfo={};
            CreateProcess(NULL,szProcess,NULL,NULL,false,0,NULL,NULL,&StartupInfo,&ProcessInfo);

            WaitForSingleObject(ProcessInfo.hProcess,3000);//INFINITE);

            CloseHandle(ProcessInfo.hThread);

            DWORD dwExitCode=0;

            GetExitCodeProcess(ProcessInfo.hProcess,&dwExitCode);

            CloseHandle(ProcessInfo.hProcess);

            SetEnvironmentVariable(_T("NELUMBO_TARGET_HWND"),NULL);
            SetEnvironmentVariable(_T("NELUMBO_SHOW_PASSWORD"),NULL);

            if(dwExitCode){
                *(phwndResult)=hWnd;
                return true;
            }else{
                *(phwndResult)=NULL;
            }
        }else{
            if(InstallMsgHook(dwThreadId)){
                if((!bShowPassword)?
                   pCallGetPassword(hWnd,g_hwndMain):
                   pCallShowPassword(hWnd,g_hwndMain)){
                    *(phwndResult)=hWnd;
                    return true;
                }
            }
        }
    }

    //パスワードの取得に失敗した場合
    HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,false,g_szEvent);
    SetEvent(hEvent);
    CloseHandle(hEvent);
    return false;
}

//ウインドウ列挙コールバック
BOOL CALLBACK EnumWindowsProc(HWND hWnd,LPARAM lParam){
    LPPARAM_ENUMWINDOWSPROC lpParam=(LPPARAM_ENUMWINDOWSPROC)lParam;
    EnumChildWindows(hWnd,(WNDENUMPROC)(lpParam->pEnumChildWindowsProc),(LPARAM)lpParam->lParam);
    return TRUE;
}

//子ウインドウ(エディットコントロール)列挙コールバック
BOOL CALLBACK EnumChildEditProc(HWND hWnd,LPARAM lParam){
    LPGETPASSWORDTHREADPARAMS lpParam=(LPGETPASSWORDTHREADPARAMS)(((LPENUMCHILDEDITPROCPARAMS)lParam)->lpparam_GetPasswordThread);
    LPENUMCHILDEDITPROCPARAMS lpParamE=(LPENUMCHILDEDITPROCPARAMS)lParam;

    if(IsPasswordmaskEditControl(hWnd)){
        //一度でも成功すればtrue
        if(!*(lpParamE->pbResult)){
            *(lpParamE->pbResult)=UnmaskPassword(lpParam->phwndResult,hWnd,(lpParam->dwKeyData[lpParam->eKeyData]&KD_EX_MASK)!=0);

            if(lpParam->eKeyData!=HOTKEY){
                HWND hWnd=ControlFromPoint();

                if(IsEditControl(hWnd)){
                    GetWindowRect(hWnd,lpParam->prcTarget);
                }
            }
            if(lpParam->prcTarget->left==-1){
                POINT pt;

                GetCursorPos(&pt);
                lpParam->prcTarget->left=pt.x;
                lpParam->prcTarget->top=pt.y;
            }
        }else{
            UnmaskPassword(lpParam->phwndResult,hWnd,(lpParam->dwKeyData[lpParam->eKeyData]&KD_EX_MASK)!=0);
        }

        HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,false,g_szEvent);
        WaitForSingleObject(hEvent,3000);//INFINITE
        ResetEvent(hEvent);
        CloseHandle(hEvent);
    }
    return TRUE;
}

//パスワードを取得するするスレッド
DWORD WINAPI GetPasswordThread(LPVOID lvParam){
    LPGETPASSWORDTHREADPARAMS lpParam=(LPGETPASSWORDTHREADPARAMS)lvParam;

    EnterCriticalSection(&g_CriticalSection);

    bool bResult=false;
    bool bFocusHookMode=(g_Config.bAutoUnmask&&lpParam->dwKeyData[lpParam->eKeyData]==KD_MODE_CLEAR);

    if(bFocusHookMode&&*(lpParam->phwndResult)||
       lpParam->dwKeyData[lpParam->eKeyData]&KD_TARGET_SINGLE){
        //ひとつのみ
        HWND hWnd=NULL;
        DWORD dwActiveProcessID=0,dwActiveThreadID=0;

        //ウインドウハンドル取得
        if(bFocusHookMode){
            hWnd=*(lpParam->phwndResult);
        }else{
            if(lpParam->eKeyData==HOTKEY){
                dwActiveThreadID=GetWindowThreadProcessId(GetForegroundWindow(),&dwActiveProcessID);
                //AttachThreadInput()しないとGetFocus()出来ない
                AttachThreadInput(GetCurrentThreadId(),dwActiveThreadID,true);
                if(!(hWnd=GetFocus())){
                    AttachThreadInput(GetCurrentThreadId(),dwActiveThreadID,false);
                }
            }else{
                hWnd=ControlFromPoint();
            }
        }

        if(hWnd&&
           IsEditControl(hWnd)&&
           SendMessage(hWnd,CB_GETEDITSEL,NULL,NULL)!=CB_ERR){
            //コンボボックスなら子ウインドウのハンドルを取得
            HWND hwndChild=GetWindow(hWnd,GW_CHILD);
            hWnd=(hwndChild&&IsPasswordmaskEditControl(hwndChild))?hwndChild:hWnd;
        }

        if(hWnd&&
           IsPasswordmaskEditControl(hWnd)){
            //パスワードマスクが有効なエディットコントロールである
            if(g_Config.bAutoUnmask&&lpParam->dwKeyData[lpParam->eKeyData]==KD_MODE_CLEAR){
                bResult=UnmaskPassword(lpParam->phwndResult,hWnd,true);
            }else{
                bResult=UnmaskPassword(lpParam->phwndResult,hWnd,(lpParam->dwKeyData[lpParam->eKeyData]&KD_EX_MASK)!=0);
            }

            HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,false,g_szEvent);
            WaitForSingleObject(hEvent,3000);//INFINITE
            ResetEvent(hEvent);
            CloseHandle(hEvent);
        }
        if(lpParam->eKeyData==HOTKEY){
            AttachThreadInput(GetCurrentThreadId(),dwActiveThreadID,false);
        }
    }else{
        ENUMCHILDEDITPROCPARAMS param_EnumChildEditProc={&bResult,lpParam};

        if(lpParam->dwKeyData[lpParam->eKeyData]&KD_TARGET_ALL){
            //画面上全て
            PARAM_ENUMWINDOWSPROC param_EnumWindowsProc={EnumChildEditProc,(LPARAM)&param_EnumChildEditProc};

            EnumWindows((WNDENUMPROC)EnumWindowsProc,(LPARAM)&param_EnumWindowsProc);
        }else if(bFocusHookMode&&!*(lpParam->phwndResult)||
                 lpParam->dwKeyData[lpParam->eKeyData]&KD_TARGET_WINDOW){
            //ウインドウ上全て
            EnumChildWindows(GetForegroundWindow(),(WNDENUMPROC)EnumChildEditProc,(LPARAM)&param_EnumChildEditProc);
        }
    }


    LeaveCriticalSection(&g_CriticalSection);
    //メインウインドウに処理終了を報告
    //WPARAMにはパスワードを取得したかどうか
    //LPARAMにはbShowPassword
    bool bShowPassword=(bFocusHookMode)?
        true:
        ((lpParam->dwKeyData[lpParam->eKeyData]&KD_EX_MASK)!=0);

    PostMessage(lpParam->hWnd,WM_EXIT_GETPASSWORD_THREAD,(WPARAM)bResult,(LPARAM)bShowPassword);
    ExitThread(0);
    return 0;
}

//パスワードマスクを解除するスレッドを作成
void CreateUnmaskPasswordThread(KEYDATA eKeyData){
    if(g_bDisable)return;

    g_bWorking=true;
    HANDLE hThread=NULL;
    DWORD dwThreadID;

    static GETPASSWORDTHREADPARAMS param_GetPasswordThread={g_hwndMain,&g_hwndTarget,&g_rcTarget};
    for(size_t i=0,size=KEYDATA_NUM;i<size;++i)param_GetPasswordThread.dwKeyData[i]=g_Config.dwKeyData[i];
    param_GetPasswordThread.eKeyData=eKeyData;

    InitializeCriticalSection(&g_CriticalSection);
    hThread=CreateThread(NULL,0,GetPasswordThread,(LPVOID)&param_GetPasswordThread,0,&dwThreadID);
    return;
}

//パスワードマスクを解除するスレッドを作成
void CreateUnmaskPasswordThread(){
    if(g_bDisable)return;

    g_bWorking=true;
    HANDLE hThread=NULL;
    DWORD dwThreadID;

    static GETPASSWORDTHREADPARAMS param_GetPasswordThread={g_hwndMain,&g_hwndTarget,&g_rcTarget};
    //良くないコード...
    param_GetPasswordThread.dwKeyData[0]=KD_MODE_CLEAR;
    param_GetPasswordThread.eKeyData=LBUTTON_WHEEL;

    InitializeCriticalSection(&g_CriticalSection);
    hThread=CreateThread(NULL,0,GetPasswordThread,(LPVOID)&param_GetPasswordThread,0,&dwThreadID);
    return;
}

//無効なメニューを有効にする
void EnableMenu(){
    for(unsigned long dwMenu=0;dwMenu<(unsigned short)-1;dwMenu++){
        int iMenuItemCount=GetMenuItemCount((HMENU)dwMenu);

        for(int iMenuCount=0;iMenuCount<=iMenuItemCount-1;iMenuCount++){
            EnableMenuItem((HMENU)dwMenu,GetMenuItemID((HMENU)dwMenu,iMenuCount),MF_ENABLED);
        }
    }
    return;
}

//子ウインドウ(コントロール)列挙コールバック
BOOL CALLBACK EnumChildControlProc(HWND hWnd,LPARAM /*lParam*/){
    EnableWindow(hWnd,true);
    return TRUE;
}

//コントロールを有効にする
void EnableControl(KEYDATA eKeyData){
    if(g_bDisable)return;

    if(g_Config.dwKeyData[eKeyData]&KD_TARGET_ALL){
        //画面上全て
        PARAM_ENUMWINDOWSPROC param_EnumWindowsProc={EnumChildControlProc};

        EnumWindows((WNDENUMPROC)EnumWindowsProc,(LPARAM)&param_EnumWindowsProc);
    }else if(g_Config.dwKeyData[eKeyData]&KD_TARGET_WINDOW){
        //ウインドウ上全て
        EnumChildWindows(GetForegroundWindow(),(WNDENUMPROC)EnumChildControlProc,(LPARAM)0);
    }else if(g_Config.dwKeyData[eKeyData]&KD_TARGET_SINGLE){
        //ひとつのみ
        EnableWindow(ControlFromPoint(),true);
    }
    if(g_Config.dwKeyData[eKeyData]&KD_EX_MENU){
        //無効なメニューも有効化
        EnableMenu();
    }
    return;
}

//パスワード表示処理やコントロール有効化処理を実行
void HandleControl(KEYDATA eKeyData){
    if(g_Config.dwKeyData[eKeyData]&KD_MODE_PASSWORD){
        if(!g_bWorking){
            CreateUnmaskPasswordThread(eKeyData);
        }
    }else if(g_Config.dwKeyData[eKeyData]&KD_MODE_CONTROL){
        EnableControl(eKeyData);
    }
    return;
}

//WM_LBUTTONDOWNのイベントハンドラ
void WmLButtonDown(){
    KEYDATA eKeyData;
    if(g_dwState&CTRLKEYDOWN){
        //Ctrl+左クリック
        eKeyData=CTRL_LBUTTON;
    }else if(g_dwState&ALTKEYDOWN){
        //Alt+左クリック
        eKeyData=ALT_LBUTTON;
    }else{
        return;
    }
    HandleControl(eKeyData);
    return;
}

///WM_RBUTTONDOWNのイベントハンドラ
void WmRButtonDown(){
    KEYDATA eKeyData;
    if(g_dwState&CTRLKEYDOWN){
        //Ctrl+右クリック
        eKeyData=CTRL_RBUTTON;
    }else if(g_dwState&ALTKEYDOWN){
        //Alt+右クリック
        eKeyData=ALT_RBUTTON;
    }else{
        return;
    }
    HandleControl(eKeyData);
    return;
}

//WM_MOUSEWHEELのイベントハンドラ
void WmMouseWheel(){
    KEYDATA eKeyData;
    if(g_dwState&LBUTTONDOWN){
        //左クリック+ホイール回転
        eKeyData=LBUTTON_WHEEL;
    }else if(g_dwState&RBUTTONDOWN){
        //右クリック+ホイール回転
        eKeyData=RBUTTON_WHEEL;
    }else if(g_dwState&CTRLKEYDOWN){
        //Ctrl+ホイール回転
        eKeyData=CTRL_WHEEL;
    }else if(g_dwState&ALTKEYDOWN){
        //Alt+ホイール回転
        eKeyData=ALT_WHEEL;
    }else{
        return;
    }
    HandleControl(eKeyData);
    return;
}

//低レベルマウスフックプロシージャ
LRESULT CALLBACK LowLevelMouseHookProc(int nCode,WPARAM wParam,LPARAM lParam){
    if(nCode<0||nCode!=HC_ACTION)return CallNextHookEx(NULL,nCode,wParam,lParam);

    switch(wParam){
        case WM_LBUTTONDOWN:
            g_dwState|=LBUTTONDOWN;
            WmLButtonDown();
            break;

        case WM_LBUTTONUP:
            g_dwState&=~LBUTTONDOWN;
            break;

        case WM_RBUTTONDOWN:
            g_dwState|=RBUTTONDOWN;
            WmRButtonDown();
            break;

        case WM_RBUTTONUP:
            g_dwState&=~RBUTTONDOWN;
            break;

        case WM_MOUSEWHEEL:
            WmMouseWheel();
            break;
    }
    return CallNextHookEx(NULL,nCode,wParam,lParam);
}

//低レベルキーボードフックプロシージャ
LRESULT CALLBACK LowLevelKeyboardHookProc(int nCode,WPARAM wParam,LPARAM lParam){
    if(nCode<0||nCode!=HC_ACTION)return CallNextHookEx(NULL,nCode,wParam,lParam);

    switch(wParam){
        case WM_SYSKEYDOWN:
            g_dwState|=ALTKEYDOWN;
            break;

        case WM_SYSKEYUP:
            g_dwState&=~ALTKEYDOWN;
            break;

        case WM_KEYDOWN:
            switch(((LPKBDLLHOOKSTRUCT)lParam)->vkCode){
                case VK_LCONTROL:
                case VK_RCONTROL:
                    g_dwState|=CTRLKEYDOWN;
                    break;
            }
            break;

        case WM_KEYUP:
            switch(((LPKBDLLHOOKSTRUCT)lParam)->vkCode){
                case VK_LCONTROL:
                case VK_RCONTROL:
                    g_dwState&=~CTRLKEYDOWN;
                    break;
            }
            break;
    }
    return CallNextHookEx(NULL,nCode,wParam,lParam);
}

//ウインドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
    //タスクトレイメニューハンドル
    static HMENU hTrayMenu;
    static HMENU hTraySubMenu;

    //パスワードメニューハンドル
    static HMENU hPasswordMenu;
    static HMENU hPasswordSubMenu;

    static HANDLE hEvent;

    static int iDefaultMenuCount;

    switch(uMsg){
        case WM_CREATE:{
            //cfgファイルを読み込む
            ReadPrivateProfile();

            //ホットキー登録
            if(g_Config.wHotKey)RegistHotKey(hWnd);

            //タスクトレイメニューを読み込む
            hTrayMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_TRAY_MENU));
            hTraySubMenu=GetSubMenu(hTrayMenu,0);

            //タスクトレイアイコン読み込み
            g_hTrayIcon=(HICON)LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
            g_hDisableTrayIcon=(HICON)LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);

            //タスクトレイにアイコン登録
            TaskTrayIcon(hWnd,NIM_ADD);

            //パスワードメニューを読み込む
            hPasswordMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_PASSWORD_MENU));
            hPasswordSubMenu=GetSubMenu(hPasswordMenu,0);

            //アイテム数を保存
            iDefaultMenuCount=GetMenuItemCount(hPasswordSubMenu);

            //手動リセットで非シグナル状態のイベントを作成
            hEvent=CreateEvent(NULL,true,false,g_szEvent);

            break;
        }

        case WM_INITMENU:{
            MENUITEMINFO MenuItemInfo={sizeof(MENUITEMINFO)};

            MenuItemInfo.fMask=MIIM_STATE;
            if(wParam==(WPARAM)hTraySubMenu){
                MenuItemInfo.fState=(g_Config.bAutoUnmask?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo(hTraySubMenu,IDM_AUTO,false,&MenuItemInfo);
                MenuItemInfo.fState=(g_bDisable?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo(hTraySubMenu,IDM_DISABLE,false,&MenuItemInfo);
            }
            break;
        }

        case WM_HOTKEY:
            switch(LOWORD(wParam)){
                case ID_HOTKEY:
                    HandleControl(HOTKEY);
                    break;
            }
            break;

        case WM_COPYDATA:{
            COPYDATASTRUCT* pCopyDataStruct=(COPYDATASTRUCT*)lParam;

            if((HWND)pCopyDataStruct->dwData==g_hwndTarget){
                TCHAR szBuffer[512]={};
                DWORD dwSize=sizeof(szBuffer);

                if(pCopyDataStruct->cbData<dwSize){
                    dwSize=pCopyDataStruct->cbData;
                }

                if(pCopyDataStruct->cbData){
                    lstrcpyn(szBuffer,(LPCTSTR)pCopyDataStruct->lpData,dwSize);

                    if(lstrlen(szBuffer)){
                        MENUITEMINFO MenuItemInfo={sizeof(MENUITEMINFO)};

                        MenuItemInfo.fMask=MIIM_ID|MIIM_TYPE;
                        MenuItemInfo.wID=GetMenuItemCount(hPasswordSubMenu);
                        MenuItemInfo.fType=MFT_STRING;
                        MenuItemInfo.dwTypeData=(LPTSTR)szBuffer;

                        InsertMenuItem(hPasswordSubMenu,-1,true,&MenuItemInfo);
                        if(g_rcTarget.left==-1)GetWindowRect(g_hwndTarget,&g_rcTarget);
                    }
                }
            }

            HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,false,g_szEvent);

            SetEvent(hEvent);
            CloseHandle(hEvent);

            g_hwndTarget=NULL;
            break;
        }

        case WM_COMMAND:
            switch(LOWORD(wParam)){
                case IDM_AUTO:
                    //自動的にパスワードマスクを解除
                    g_Config.bAutoUnmask=!g_Config.bAutoUnmask;
                    break;

                case IDM_DISABLE:
                    //反転
                    g_bDisable=!g_bDisable;
                    TaskTrayIcon(hWnd,NIM_MODIFY,!g_bDisable);
                    break;

                case IDM_SETTINGS:
                case IDM_ABOUT:
                    if(!g_bSettingsDialog){
                        g_bSettingsDialog=true;
                        //ホットキー登録解除
                        if(g_Config.wHotKey)UnregistHotKey(hWnd);
                        //設定ダイアログ表示
                        ShowSettingsDialog(hWnd,(LOWORD(wParam==IDM_SETTINGS))?0:1);
                        //ホットキー登録
                        if(g_Config.wHotKey)RegistHotKey(hWnd);
                        g_bSettingsDialog=false;
                    }
                    break;

                case IDM_EXIT:
                    SendMessage(hWnd,WM_CLOSE,(WPARAM)0,(LPARAM)0);
                    break;

                default:
                    break;
            }
            break;

        case WM_EXIT_GETPASSWORD_THREAD:{
            //WPARAMにはパスワードを取得したかどうか
            //LPARAMにはbShowPassword
            if(g_hGetPasswordThread!=NULL){
                DeleteCriticalSection(&g_CriticalSection);
                CloseHandle(g_hGetPasswordThread);
                g_hGetPasswordThread=NULL;
            }

            //最後のフックを解除
            UninstallMsgHook();

            if(wParam&&
               !lParam&&
               GetMenuItemCount(hPasswordSubMenu)>iDefaultMenuCount){
                //パスワードの取得に成功している場合
                SetForegroundWindowEx(hWnd);

                UINT uId=0;

                if((uId=TrackPopupMenu(hPasswordSubMenu,
                                       TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_RETURNCMD,
                                       g_rcTarget.left,g_rcTarget.top,
                                       0,
                                       hWnd,
                                       NULL))){

                    TCHAR szBuffer[256]={};

                    GetMenuString(hPasswordMenu,uId,szBuffer,ARRAY_SIZEOF(szBuffer),MF_BYCOMMAND);
                    //クリップボードにコピー
                    SetClipboardText(hWnd,szBuffer,lstrlen(szBuffer));
                }

                for(int i=GetMenuItemCount(hPasswordSubMenu)-1;i>=iDefaultMenuCount;i--){
                    RemoveMenu(hPasswordSubMenu,i,MF_BYPOSITION);
                }
            }
            if(!lParam){
                g_rcTarget.left=g_rcTarget.right=g_rcTarget.top=g_rcTarget.bottom=-1;
            }
            g_bWorking=false;
            break;
        }

        case WM_CLOSE:
            //cfgファイルに書き込む
            WritePrivateProfile();
            CloseHandle(hEvent);
            //ホットキー登録解除
            UnregistHotKey(hWnd);
            DestroyMenu(hTrayMenu);
            hTrayMenu=NULL;
            TaskTrayIcon(hWnd,NIM_DELETE,false);
            DestroyMenu(hPasswordMenu);
            hPasswordMenu=NULL;
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    if(uMsg==MSG_TRAYMENU&&
       wParam==ID_TRAYMENU){
        if(lParam==WM_LBUTTONDOWN){
            SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDM_SETTINGS,0),0);
        }else if(lParam==WM_RBUTTONDOWN){
            POINT pt;

            GetCursorPos(&pt);
            SetForegroundWindowEx(hWnd);
            TrackPopupMenu(hTraySubMenu,TPM_BOTTOMALIGN,pt.x,pt.y,0,hWnd,NULL);
        }
    }

    if(uMsg==MSG_TASKBARCREATED){
        TaskTrayIcon(hWnd,NIM_ADD,true);
    }else if(g_Config.bAutoUnmask&&
             uMsg==WM_HOOKDIALOG){
        HWND hTarget=(HWND)wParam;

        if(hTarget&&
           IsEditControl(hTarget)&&
           SendMessage(hTarget,CB_GETEDITSEL,NULL,NULL)!=CB_ERR){
            //コンボボックスなら子ウインドウのハンドルを取得
            HWND hwndChild=GetWindow(hTarget,GW_CHILD);
            hTarget=(hwndChild&&IsPasswordmaskEditControl(hwndChild))?hwndChild:hTarget;
        }
        if(IsPasswordmaskEditControl(hTarget)){
            g_hwndTarget=hTarget;
            CreateUnmaskPasswordThread();
        }
    }

    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

//低レベルマウスフックをインストールするスレッド
DWORD WINAPI LowLevelMouseHookThread(LPVOID lpParam){
    MSG msg;

    if((g_hkMouseHook=SetWindowsHookEx(WH_MOUSE_LL,LowLevelMouseHookProc,g_hInstance,0))==NULL){
        return GetLastError();
    }

    while(GetMessage(&msg,0,0,0)>0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    ExitThread(0);
    return 0;
}

//低レベルキーボードフックをインストールするスレッド
DWORD WINAPI LowLevelKeyboardHookThread(LPVOID lpParam){
    MSG msg;

    if((g_hkKeyboardHook=SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardHookProc,g_hInstance,0))==NULL){
        return GetLastError();
    }

    while(GetMessage(&msg,0,0,0)>0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    ExitThread(0);
    return 0;
}

//ウインドウクラスを登録
bool InitApplication(HINSTANCE hInstance,LPCTSTR lpszClassName){
    WNDCLASS wc;

    wc.style        =CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc  =(WNDPROC)WindowProc;
    wc.cbClsExtra   =0;
    wc.cbWndExtra   =0;
    wc.hInstance    =hInstance;
    wc.hIcon        =NULL;
    wc.hCursor      =NULL;
    wc.hbrBackground=NULL;
    wc.lpszMenuName =NULL;
    wc.lpszClassName=lpszClassName;
    return RegisterClass(&wc)!=0;
}

//エントリポイント
#ifndef _DEBUG
extern "C" void WinMainCRTStartup(){
#else
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow){
#endif
    HANDLE hMutex=NULL;
    HWND hWnd=NULL,hFindWindow=NULL;
    MSG msg;
    hMutex=CreateMutex(NULL,true,_T("{22D1D183-ABF7-42c3-B0A1-C3E5E975A3B7}"));

    //既に起動している場合どちらも終了する
    if(GetLastError()==ERROR_ALREADY_EXISTS){
        hFindWindow=FindWindow(NELUMBO_CLASS_NAME,NULL);
        if(hFindWindow){
            SendMessage(hFindWindow,WM_CLOSE,(WPARAM)0,(LPARAM)0);
        }
        ExitProcess(0);
    }

    g_hInstance=GetModuleHandle(NULL);

    //タスクトレイ用メッセージ登録
    MSG_TRAYMENU=RegisterWindowMessage(_T("MSG_TRAYMENU"));
    //タスクバー再作成用メッセージ登録
    MSG_TASKBARCREATED=RegisterWindowMessage(_T("TaskbarCreated"));

    if(!InitApplication(g_hInstance,NELUMBO_CLASS_NAME)){
        ExitProcess(1);
    }

    hWnd=CreateWindow(NELUMBO_CLASS_NAME,
                      NULL,
                      0,
                      0,0,
                      0,0,
                      NULL,
                      NULL,
                      g_hInstance,
                      NULL);

    if(hWnd==NULL){
        ExitProcess(1);
    }

    g_hwndMain=hWnd;

    WM_HOOKDIALOG=RegisterWindowMessage(_T("_WM_HOOKDIALOG_"));
    g_hHookDll=LoadLibrary(_T("MsgHook.dll"));

    if(g_hHookDll!=NULL){
        pInstallMsgHook=(INSTALLMSGHOOK_PTR)GetProcAddress(g_hHookDll,"InstallMsgHook");
        pCallGetPassword=(CALLGETPASSWORD_PTR)GetProcAddress(g_hHookDll,"CallGetPassword");
        pCallShowPassword=(CALLSHOWPASSWORD_PTR)GetProcAddress(g_hHookDll,"CallShowPassword");
        pUninstallMsgHook=(UNINSTALLMSGHOOK_PTR)GetProcAddress(g_hHookDll,"UninstallMsgHook");

        pInstallFocusHook=(INSTALLFOCUSHOOK_PTR)GetProcAddress(g_hHookDll,"InstallFocusHook");
        pUninstallFocusHook=(UNINSTALLFOCUSHOOK_PTR)GetProcAddress(g_hHookDll,"UninstallFocusHook");

        pInstallFocusHook(hWnd,WM_HOOKDIALOG);
    }

    //マウスフックインストール
    HANDLE hMouseHookThread=CreateThread(NULL,0,LowLevelMouseHookThread,NULL,0,NULL);
    //キーボードフックインストール
    HANDLE hKeyboardHookThread=CreateThread(NULL,0,LowLevelKeyboardHookThread,NULL,0,NULL);


    SetEnvironmentVariable(_T("NELUMBO64_MODE"),_T("FocusHookMode"));
    TCHAR szProcess[]=_T("Nelumbo64");
    STARTUPINFO StartupInfo={sizeof(STARTUPINFO)};
    PROCESS_INFORMATION ProcessInfo={0};

    CreateProcess(NULL,szProcess,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo);
    SetEnvironmentVariable(_T("NELUMBO64_MODE"),NULL);


#define MSGFLT_ALLOW 1
#define MSGFLT_RESET 0
#define MSGFLT_ADD 1
#define MSGFLT_REMOVE 2

    //メッセージ受信許可
    typedef BOOL(WINAPI*PCHANGEWINDOWMESSAGEFILTEREX)(HWND,UINT,DWORD,int);
    typedef BOOL(WINAPI*PCHANGEWINDOWMESSAGEFILTER)(UINT,DWORD);

    PCHANGEWINDOWMESSAGEFILTEREX pChangeWindowMessageFilterEx=NULL;
    PCHANGEWINDOWMESSAGEFILTER pChangeWindowMessageFilter=NULL;

    pChangeWindowMessageFilterEx=(PCHANGEWINDOWMESSAGEFILTEREX)GetProcAddress(GetModuleHandle(_T("user32")),"ChangeWindowMessageFilterEx");

    if(pChangeWindowMessageFilterEx){
        pChangeWindowMessageFilterEx(hWnd,WM_COPYDATA,MSGFLT_ALLOW,0);
        pChangeWindowMessageFilterEx(hWnd,WM_HOOKDIALOG,MSGFLT_ALLOW,0);
    }else{
        pChangeWindowMessageFilter=(PCHANGEWINDOWMESSAGEFILTER)GetProcAddress(GetModuleHandle(_T("user32")),"ChangeWindowMessageFilter");
        if(pChangeWindowMessageFilter){
            pChangeWindowMessageFilter(WM_COPYDATA,MSGFLT_ADD);
            pChangeWindowMessageFilter(WM_HOOKDIALOG,MSGFLT_ADD);
        }
    }

    while(GetMessage(&msg,NULL,0,0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if(pChangeWindowMessageFilterEx){
        pChangeWindowMessageFilterEx(hWnd,WM_COPYDATA,MSGFLT_RESET,0);
        pChangeWindowMessageFilterEx(hWnd,WM_HOOKDIALOG,MSGFLT_RESET,0);
    }else if(pChangeWindowMessageFilter){
        pChangeWindowMessageFilter(WM_COPYDATA,MSGFLT_REMOVE);
        pChangeWindowMessageFilter(WM_HOOKDIALOG,MSGFLT_REMOVE);
    }

    UninstallMsgHook();
    pUninstallFocusHook();
    FreeLibrary(g_hHookDll);

    if(WaitForSingleObject(hMouseHookThread,1000)==WAIT_TIMEOUT){
        TerminateThread(hMouseHookThread,0);
        CloseHandle(hMouseHookThread);
    }
    if(WaitForSingleObject(hKeyboardHookThread,1000)==WAIT_TIMEOUT){
        TerminateThread(hKeyboardHookThread,0);
        CloseHandle(hKeyboardHookThread);
    }

    //マウスフックアンインストール
    UnhookWindowsHookEx(g_hkMouseHook);
    //キーボードフックアンインストール
    UnhookWindowsHookEx(g_hkKeyboardHook);

    hFindWindow=FindWindow(NELUMBO_CLASS_NAME64,NULL);
    if(hFindWindow){
        SendMessage(hFindWindow,WM_CLOSE,(WPARAM)0,(LPARAM)0);
    }

    ExitProcess((UINT)msg.wParam);
}


Home > ソフトウェア > Nelumbo > Nelumbo172.zip > Src > Nelumbo.cpp