BOOLEAN PhpInitializePropSheetLayoutStage1( _In_ PPH_PROCESS_PROPSHEETCONTEXT Context, _In_ HWND hwnd ) { if (!Context->LayoutInitialized) { HWND tabControlHandle; PPH_LAYOUT_ITEM tabControlItem; PPH_LAYOUT_ITEM tabPageItem; tabControlHandle = PropSheet_GetTabControl(hwnd); tabControlItem = PhAddLayoutItem(&Context->LayoutManager, tabControlHandle, NULL, PH_ANCHOR_ALL | PH_LAYOUT_IMMEDIATE_RESIZE); tabPageItem = PhAddLayoutItem(&Context->LayoutManager, tabControlHandle, NULL, PH_LAYOUT_TAB_CONTROL); // dummy item to fix multiline tab control Context->TabPageItem = tabPageItem; PhAddLayoutItem(&Context->LayoutManager, GetDlgItem(hwnd, IDCANCEL), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); // Hide the OK button. ShowWindow(GetDlgItem(hwnd, IDOK), SW_HIDE); // Set the Cancel button's text to "Close". PhSetDialogItemText(hwnd, IDCANCEL, L"Close"); Context->LayoutInitialized = TRUE; return TRUE; } return FALSE; }
/* This function handles the WM_NOTIFY message. */ LRESULT FASTCALL RASBlinkProperties_OnNotify( HWND hwnd, int code, LPNMHDR lpnmhdr ) { switch( lpnmhdr->code ) { case PSN_HELP: HtmlHelp( hwnd, szHelpFile, HH_HELP_CONTEXT, idsBLINK_RAS ); break; case PSN_APPLY: { LPBLINKENTRY lpbe; HWND hwndTab; /* Update the blink entry structure. */ lpbe = (LPBLINKENTRY)GetWindowLong( hwnd, DWL_USER ); hwndTab = PropSheet_GetTabControl( GetParent( hwnd ) ); if( !TabCtrl_GetEnable( hwndTab, idRasTab ) ) lpbe->rd.fUseRAS = FALSE; else lpbe->rd.fUseRAS = IsDlgButtonChecked( hwnd, IDD_USERAS ); /* If we use RAS, we'll need the entry name. */ if( lpbe->rd.fUseRAS ) { HWND hwndList; /* Get the entry name. */ hwndList = GetDlgItem( hwnd, IDD_LIST ); ComboBox_GetText( hwndList, lpbe->rd.szRASEntryName, RAS_MaxEntryName+1 ); /* Get username and password. */ Edit_GetText( GetDlgItem( hwnd, IDD_USERNAME ), lpbe->rd.szRASUserName, UNLEN+1 ); Edit_GetText( GetDlgItem( hwnd, IDD_PASSWORD ), lpbe->rd.szRASPassword, PWLEN+1 ); if( ( strlen( lpbe->rd.szRASEntryName ) == 0 ) || ( strlen( lpbe->rd.szRASUserName ) == 0 ) || ( strlen( lpbe->rd.szRASPassword ) == 0 ) ) { fMessageBox( hwnd, 0, GS(IDS_STR1242), MB_OK|MB_ICONEXCLAMATION ); return( PSNRET_INVALID_NOCHANGEPAGE ); } Amuser_Encrypt( lpbe->rd.szRASPassword, rgEncodeKey ); } /* Force the Apply button to be disabled. */ PropSheet_UnChanged( GetParent( hwnd ), hwnd ); return( PSNRET_NOERROR ); } } return( FALSE ); }
void UpdateStrings() { // Update window title PropSheet_SetTitle(g_cfgwnd, 0, l10n->title); // Update tab titles HWND tc = PropSheet_GetTabControl(g_cfgwnd); int numrows_prev = TabCtrl_GetRowCount(tc); wchar_t *titles[] = { l10n->tab_general, l10n->tab_input, l10n->tab_blacklist, l10n->tab_advanced, l10n->tab_about }; int i; for (i=0; i < ARRAY_SIZE(titles); i++) { TCITEM ti; ti.mask = TCIF_TEXT; ti.pszText = titles[i]; TabCtrl_SetItem(tc, i, &ti); } // Modify UI if number of rows have changed int numrows = TabCtrl_GetRowCount(tc); if (numrows_prev != numrows) { HWND page = PropSheet_GetCurrentPageHwnd(g_cfgwnd); if (page != NULL) { int diffrows = numrows-numrows_prev; WINDOWPLACEMENT wndpl = { sizeof(WINDOWPLACEMENT) }; // Resize window GetWindowPlacement(g_cfgwnd, &wndpl); wndpl.rcNormalPosition.bottom += 18*diffrows; SetWindowPlacement(g_cfgwnd, &wndpl); // Resize tabcontrol GetWindowPlacement(tc, &wndpl); wndpl.rcNormalPosition.bottom += 18*diffrows; SetWindowPlacement(tc, &wndpl); // Move button HWND button = GetDlgItem(g_cfgwnd, IDOK); GetWindowPlacement(button, &wndpl); int height = wndpl.rcNormalPosition.bottom-wndpl.rcNormalPosition.top; wndpl.rcNormalPosition.top += 18*diffrows; wndpl.rcNormalPosition.bottom = wndpl.rcNormalPosition.top+height; SetWindowPlacement(button, &wndpl); // Re-select tab PropSheet_SetCurSel(g_cfgwnd, page, 0); // Invalidate region GetWindowPlacement(g_cfgwnd, &wndpl); InvalidateRect(g_cfgwnd, &wndpl.rcNormalPosition, TRUE); } } }
/*! 独自拡張プロパティシートのウィンドウプロシージャ @author ryoji @date 2007.05.25 新規 */ static LRESULT CALLBACK PropSheetWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch( uMsg ){ case WM_SHOWWINDOW: // 追加ボタンの位置を調整する if( wParam ){ HWND hwndBtn; RECT rcOk; RECT rcTab; POINT pt; hwndBtn = ::GetDlgItem( hwnd, 0x02000 ); ::GetWindowRect( ::GetDlgItem( hwnd, IDOK ), &rcOk ); ::GetWindowRect( PropSheet_GetTabControl( hwnd ), &rcTab ); pt.x = rcTab.left; pt.y = rcOk.top; ::ScreenToClient( hwnd, &pt ); ::MoveWindow( hwndBtn, pt.x, pt.y, DpiScaleX(140), rcOk.bottom - rcOk.top, FALSE ); } break; case WM_COMMAND: // 追加ボタンが押された時はその処理を行う if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == 0x02000 ){ HWND hwndBtn = ::GetDlgItem( hwnd, 0x2000 ); RECT rc; POINT pt; // メニューを表示する ::GetWindowRect( hwndBtn, &rc ); pt.x = rc.left; pt.y = rc.bottom; GetMonitorWorkRect( pt, &rc ); // モニタのワークエリア HMENU hMenu = ::CreatePopupMenu(); ::InsertMenu( hMenu, 0, MF_BYPOSITION | MF_STRING, 100, LS(STR_SHELL_MENU_OPEN) ); ::InsertMenu( hMenu, 1, MF_BYPOSITION | MF_STRING, 101, LS(STR_SHELL_MENU_IMPEXP) ); int nId = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD, ( pt.x > rc.left )? pt.x: rc.left, ( pt.y < rc.bottom )? pt.y: rc.bottom, 0, hwnd, NULL ); ::DestroyMenu( hMenu ); // 選択されたメニューの処理 switch( nId ){ case 100: // 設定フォルダを開く TCHAR szPath[_MAX_PATH]; GetInidir( szPath ); // フォルダの ITEMIDLIST を取得して ShellExecuteEx() で開く // Note. MSDN の ShellExecute() の解説にある方法でフォルダを開こうとした場合、 // フォルダと同じ場所に <フォルダ名>.exe があるとうまく動かない。 // verbが"open"やNULLではexeのほうが実行され"explore"では失敗する // (フォルダ名の末尾に'\\'を付加してもWindows 2000では付加しないのと同じ動作になってしまう) LPSHELLFOLDER pDesktopFolder; if( SUCCEEDED(::SHGetDesktopFolder(&pDesktopFolder)) ){ LPMALLOC pMalloc; if( SUCCEEDED(::SHGetMalloc(&pMalloc)) ){ LPITEMIDLIST pIDL; WCHAR pwszDisplayName[_MAX_PATH]; _tcstowcs(pwszDisplayName, szPath, _countof(pwszDisplayName)); //#ifdef _UNICODE // pwszDisplayName = szPath; //#else // WCHAR wszPath[_MAX_PATH]; // ::MultiByteToWideChar( CP_ACP, 0, szPath, -1, wszPath, _MAX_PATH ); // pwszDisplayName = wszPath; //#endif if( SUCCEEDED(pDesktopFolder->ParseDisplayName(NULL, NULL, pwszDisplayName, NULL, &pIDL, NULL)) ){ SHELLEXECUTEINFO si; ::ZeroMemory( &si, sizeof(si) ); si.cbSize = sizeof(si); si.fMask = SEE_MASK_IDLIST; si.lpVerb = _T("open"); si.lpIDList = pIDL; si.nShow = SW_SHOWNORMAL; ::ShellExecuteEx( &si ); // フォルダを開く pMalloc->Free( (void*)pIDL ); } pMalloc->Release(); } pDesktopFolder->Release(); } break; case 101: // インポート/エクスポートの起点リセット(起点を設定フォルダにする) int nMsgResult = MYMESSAGEBOX( hwnd, MB_OKCANCEL | MB_ICONINFORMATION, GSTR_APPNAME, LS(STR_SHELL_IMPEXPDIR) ); if( IDOK == nMsgResult ) { DLLSHAREDATA *pShareData = &GetDllShareData(); GetInidir( pShareData->m_sHistory.m_szIMPORTFOLDER ); AddLastChar( pShareData->m_sHistory.m_szIMPORTFOLDER, _countof2(pShareData->m_sHistory.m_szIMPORTFOLDER), _T('\\') ); } break; } } break; case WM_DESTROY: ::SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)s_pOldPropSheetWndProc ); break; } return ::CallWindowProc( s_pOldPropSheetWndProc, hwnd, uMsg, wParam, lParam ); }
LRESULT CALLBACK PhpPropSheetWndProc( _In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PPH_PROCESS_PROPSHEETCONTEXT propSheetContext; WNDPROC oldWndProc; propSheetContext = PhGetWindowContext(hwnd, 0xF); if (!propSheetContext) return 0; oldWndProc = propSheetContext->PropSheetWindowHookProc; switch (uMsg) { case WM_DESTROY: { HWND tabControl; TCITEM tabItem; WCHAR text[128]; // Save the window position and size. PhSaveWindowPlacementToSetting(L"ProcPropPosition", L"ProcPropSize", hwnd); // Save the selected tab. tabControl = PropSheet_GetTabControl(hwnd); tabItem.mask = TCIF_TEXT; tabItem.pszText = text; tabItem.cchTextMax = RTL_NUMBER_OF(text) - 1; if (TabCtrl_GetItem(tabControl, TabCtrl_GetCurSel(tabControl), &tabItem)) { PhSetStringSetting(L"ProcPropPage", text); } } break; case WM_NCDESTROY: { PhUnregisterWindowCallback(hwnd); SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)oldWndProc); PhRemoveWindowContext(hwnd, 0xF); PhDeleteLayoutManager(&propSheetContext->LayoutManager); PhFree(propSheetContext); } break; case WM_SYSCOMMAND: { // Note: Clicking the X on the taskbar window thumbnail preview doens't close modeless property sheets // when there are more than 1 window and the window doesn't have focus... The MFC, ATL and WTL libraries // check if the propsheet is modeless and SendMessage WM_CLOSE and so we'll implement the same solution. (dmex) switch (wParam & 0xFFF0) { case SC_CLOSE: { PostMessage(hwnd, WM_CLOSE, 0, 0); //SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); //return TRUE; } break; } } break; case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: // Prevent the OK button from working (even though // it's already hidden). This prevents the Enter // key from closing the dialog box. return 0; } } break; case WM_SIZE: { if (!IsMinimized(hwnd)) { PhLayoutManagerLayout(&propSheetContext->LayoutManager); } } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; } return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam); }