パッと見ライト&Eメールの起動ボタンで、該当するメールの閲覧画面をなんとか直接開けないものか。
あともう一歩のところまで解析できたのでまとめてみた。
■一番簡単そうな方法は、W-ZERO3メールに直接キーイベント(右右)を送ってしまう方法。
W-ZERO3メール起動直後で、ツリービューの受信トレイにフォーカスがある状態かつ、リストビューの日付が新しい順ソートになっているという前提なら、一番新しいメールを開くことができる。
HWND hwnd = FindWindow(L"WCE_STMailMainFrame", L"W-ZERO3メール ");
SetForegroundWindow(hwnd);
//右押下(これを2回)
keybd_event(VK_RIGHT, 0, 0, 0);
keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
リストビューまではSetFocusで移動させたかったんだけど、WindowsMobileではAttachThreadInputが無くて他プロセスのSetFocusは無理みたい・・・
■なんとか日付順ソートにしたい。マウスイベントを送って日付順に変えてみることにした。
日付のソート状態が確認できないので、まず差出人クリックしてから、日付クリックを2回、右押下という手順。
//ListViewのハンドル取得(アドエスの場合)
HWND hwnd4 = GetDlgItem(hwnd, 0x436);
//リストビューとスクリーンの位置・サイズを取得(省略)
//差出人タブあたりにマウス移動して、クリック
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
65536 / screenWidth * 100, 65536 / screenHeight * (ListViewTop + 50), 0, NULL);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, NULL);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, NULL);
//時間タブあたりにマウス移動して、クリック
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
65536 / screenWidth * 420, 65536 / screenHeight * (ListViewTop + 50), 0, NULL);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, NULL);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, NULL);
//位置を若干ずらしてもう1回クリックで降順にする(省略)
//リストビューのn番目を選択状態にする
//他プロセスなので、CreateFileMappingで共有可能なメモリで構造体を作って渡す必要がある。
HANDLE hFileMapping = CreateFileMapping((HANDLE)0xFFFFFFFF, 0, PAGE_READWRITE, 0, sizeof(LVITEM), 0);
LVITEM *_ms_lvi = (LVITEM*)MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
//全選択解除
_ms_lvi->stateMask = LVIS_SELECTED | LVIS_FOCUSED;
_ms_lvi->state = 0;
SNDMSG(hwnd4, LVM_SETITEMSTATE, -1, (LPARAM)(LVITEM FAR *)_ms_lvi);
//n番目を選択する
_ms_lvi->stateMask = LVIS_SELECTED | LVIS_FOCUSED;
_ms_lvi->state = LVIS_SELECTED | LVIS_FOCUSED;
SNDMSG(hwnd4, LVM_SETITEMSTATE, n, (LPARAM)(LVITEM FAR *)_ms_lvi);
UnmapViewOfFile(_ms_lvi);
CloseHandle(hFileMapping);
//右押下でメール表示
keybd_event(VK_RIGHT, 0, 0, 0);
keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
■おまけで件数や状態を取得する方法。
//選択件数
int cnt = ListView_GetSelectedCount(hwnd4);
//選択位置
int cnt2 = ListView_GetNextItem(hwnd4, -1, LVNI_SELECTED);
//リスト件数
int cnt3 = ListView_GetItemCount(hwnd4);
//n番目のリストの選択状態
UINT uiState1 = ListView_GetItemState( hwnd4, n, LVIS_SELECTED | LVIS_FOCUSED );
//ヘッダの項目数
int iCount = Header_GetItemCount(ListView_GetHeader(hwnd4));
//n番目のヘッダのサイズ
DWORD w1 = ListView_GetColumnWidth(hwnd4, n);
■最後にもういっちょおまけで、リストの文字列を取得する方法。
差出人やタイトルとの照らし合わせすれば制度が上がるかも。
//ListView_GetItemTextをそのまま使ってもNGなので、他プロセス用のメモリを割り当てて取得する。
HANDLE hFileMapping2 = CreateFileMapping((HANDLE)0xFFFFFFFF, 0, PAGE_READWRITE, 0, sizeof(LV_ITEM), 0);
LV_ITEM *pLvItem = (LV_ITEM*)MapViewOfFile(hFileMapping2, FILE_MAP_WRITE, 0, 0, 0);
pLvItem->iSubItem = 1;
pLvItem->cchTextMax = 256;
pLvItem->pszText = 0;
int icnt = SNDMSG(hwnd4, LVM_GETITEMTEXT, (WPARAM)1, (LPARAM)(LV_ITEM FAR *)pLvItem);
wchar_t text[256];
DWORD intPID;
DWORD intRdCnt;
GetWindowThreadProcessId(hwnd4, &intPID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, intPID);
ReadProcessMemory(hProc, pLvItem->pszText, text, 256, &intRdCnt);
CloseHandle(hProc);
UnmapViewOfFile(pLvItem);
CloseHandle(hFileMapping2);