283 lines
7.8 KiB
C++
283 lines
7.8 KiB
C++
|
/*
|
||
|
* 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);
|
||
|
}
|