Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

282 lines
7.8 KiB

/*
* common - Common user interface services
*/
#include "tweakui.h"
/*****************************************************************************
*
* Common_SetDirty
*
* Make a property sheet dirty.
*
*****************************************************************************/
void NEAR PASCAL
Common_SetDirty(HWND hdlg)
{
PropSheet_Changed(GetParent(hdlg), hdlg);
}
/*****************************************************************************
*
* Common_NeedLogoff
*
* Indicate that you need to log off for the changes to take effect.
*
*****************************************************************************/
void NEAR PASCAL
Common_NeedLogoff(HWND hdlg)
{
PropSheet_RestartWindows(GetParent(hdlg));
}
/*****************************************************************************
*
* Common_OnHelp
*
* Respond to the F1 key.
*
*****************************************************************************/
void PASCAL
Common_OnHelp(LPARAM lp, const DWORD CODESEG *pdwHelp)
{
WinHelp((HWND) ((LPHELPINFO) lp)->hItemHandle, c_tszMyHelp,
HELP_WM_HELP, (DWORD_PTR) pdwHelp);
}
/*****************************************************************************
*
* Common_OnContextMenu
*
* Respond to a right-click.
*
*****************************************************************************/
void PASCAL
Common_OnContextMenu(WPARAM wp, const DWORD CODESEG *pdwHelp)
{
WinHelp((HWND) wp, c_tszMyHelp, HELP_CONTEXTMENU, (DWORD_PTR) pdwHelp);
}
/*****************************************************************************
*
* Common_OnLvContextMenu
*
* The context menu shall appear in the listview.
*
* Have the callback generate the menu, then pop it up and let the
* window procedure's WM_COMMAND do the rest.
*
*****************************************************************************/
void PASCAL
Common_OnLvContextMenu(HWND hwnd, POINT pt, CMCALLBACK pfn)
{
int iItem = Misc_LV_GetCurSel(hwnd);
if (iItem != -1) {
ClientToScreen(hwnd, &pt); /* Make it screen coordinates */
TrackPopupMenuEx(pfn(hwnd, iItem),
TPM_RIGHTBUTTON | TPM_VERTICAL |
TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y,
GetParent(hwnd), 0);
}
}
/*****************************************************************************
*
* Common_LV_OnContextMenu
*
* If the context menu came from the listview, figure out which
* item got clicked on. If we find an item, pop up its context
* menu. Otherwise, just do the standard help thing.
*
* NOTE! We don't use LVHT_ONITEM because ListView is broken!
* Watch:
*
* #define LVHT_ONITEMSTATEICON 0x0008
* #define LVHT_ABOVE 0x0008
*
* Oops. This means that clicks above the item are treated as
* clicks on the state icon.
*
* Fortunately, we reside completely in report view, so you can't
* legally click above the item. The only way it can happen is
* if the coordinates to OnContextMenu are out of range, so we
* catch that up front and munge it accordingly.
*
*****************************************************************************/
void PASCAL
Common_LV_OnContextMenu(HWND hdlg, HWND hwnd, LPARAM lp,
CMCALLBACK pfn, const DWORD CODESEG *pdwHelp)
{
if (GetDlgCtrlID(hwnd) == IDC_LISTVIEW) {
LV_HITTESTINFO hti;
if (lp == (LPARAM)0xFFFFFFFF) {
/* Pretend it was on the center of the small icon */
ListView_GetItemPosition(hwnd, Misc_LV_GetCurSel(hwnd),
&hti.pt);
hti.pt.x += GetSystemMetrics(SM_CXSMICON) / 2;
hti.pt.y += GetSystemMetrics(SM_CYSMICON) / 2;
Common_OnLvContextMenu(hwnd, hti.pt, pfn);
} else {
Misc_LV_HitTest(hwnd, &hti, lp);
if ((hti.flags & LVHT_ONITEM)) {
/* Because LV sometimes forgets to move the focus... */
Misc_LV_SetCurSel(hwnd, hti.iItem);
Common_OnLvContextMenu(hwnd, hti.pt, pfn);
} else {
Common_OnContextMenu((WPARAM)hwnd, pdwHelp);
}
}
} else {
Common_OnContextMenu((WPARAM)hwnd, pdwHelp);
}
}
/*****************************************************************************
*
* Common_OnLvCommand
*
* Handle a WM_COMMAND that might be for the listview.
*
*****************************************************************************/
void PASCAL
Common_OnLvCommand(HWND hdlg, int idCmd, PLVCI rglvci, int clvci)
{
do {
if (idCmd == rglvci[0].id) {
HWND hwnd = GetDlgItem(hdlg, IDC_LISTVIEW);
int iItem = Misc_LV_GetCurSel(hwnd);
if (iItem != -1) {
rglvci[0].pfn(hwnd, iItem);
}
break;
}
rglvci++;
} while (--clvci);
}
/*****************************************************************************
*
* EnableDlgItem
*
* A simple wrapper.
*
*****************************************************************************/
void NEAR PASCAL
EnableDlgItem(HWND hdlg, UINT idc, BOOL f)
{
EnableWindow(GetDlgItem(hdlg, idc), f);
}
/*****************************************************************************
*
* EnableDlgItems
*
*****************************************************************************/
void NEAR PASCAL
EnableDlgItems(HWND hdlg, UINT idcFirst, UINT idcLast, BOOL f)
{
for (; idcFirst <= idcLast; idcFirst++) {
EnableWindow(GetDlgItem(hdlg, idcFirst), f);
}
}
/*****************************************************************************
*
* AdjustDlgItems
*
*****************************************************************************/
void NEAR PASCAL
AdjustDlgItems(HWND hdlg, UINT idcFirst, UINT idcLast, UINT adi)
{
for (UINT idc = idcFirst; idc <= idcLast; idc++) {
HWND hwnd = GetDlgItem(hdlg, idc);
if (adi & (ADI_DISABLE | ADI_ENABLE)) {
EnableWindow(hwnd, (adi & ADI_ENABLE) ? TRUE : FALSE);
}
if (adi & (ADI_HIDE | ADI_SHOW)) {
ShowWindow(hwnd, (adi & ADI_SHOW) ? SW_SHOW : SW_HIDE);
}
}
}
/*****************************************************************************
*
* SetDlgItemTextLimit
*
* Set the dialog item text as well as limiting its size.
*
*****************************************************************************/
void NEAR PASCAL
SetDlgItemTextLimit(HWND hdlg, UINT id, LPCTSTR ptsz, UINT ctch)
{
HWND hwnd = GetDlgItem(hdlg, id);
SetWindowText(hwnd, ptsz);
Edit_LimitText(hwnd, ctch - 1);
}
/*****************************************************************************
*
* DestroyDlgItems
*
*****************************************************************************/
void NEAR PASCAL
DestroyDlgItems(HWND hdlg, UINT idcFirst, UINT idcLast)
{
UINT idc;
for (idc = idcFirst; idc <= idcLast; idc++) {
DestroyWindow(GetDlgItem(hdlg, idc));
}
}
/*****************************************************************************
*
* GetDlgItemRect
*
* Get the rect of a dialog item in client coordinates.
*
*****************************************************************************/
void PASCAL
GetDlgItemRect(HWND hdlg, UINT idc, LPRECT prc)
{
GetWindowRect(GetDlgItem(hdlg, idc), prc);
MapWindowRect(NULL, hdlg, prc);
}
/*****************************************************************************
*
* MoveDlgItems
*
*****************************************************************************/
void PASCAL
MoveDlgItems(HWND hdlg, UINT idcTarget, UINT idcFirst, UINT idcLast)
{
RECT rcFrom, rcTo;
GetDlgItemRect(hdlg, idcTarget, &rcTo);
GetDlgItemRect(hdlg, idcFirst, &rcFrom);
int dy = rcTo.top - rcFrom.top;
HDWP hdwp = BeginDeferWindowPos(idcLast - idcFirst + 1);
for (UINT idc = idcFirst; idc <= idcLast; idc++) {
GetDlgItemRect(hdlg, idc, &rcFrom);
HWND hwnd = GetDlgItem(hdlg, idc);
hdwp = DeferWindowPos(hdwp, hwnd, NULL,
rcFrom.left, rcFrom.top + dy, 0, 0,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
}
EndDeferWindowPos(hdwp);
}