- Add a cute custom control to sysdm allowing dialogs to display hyperlink style text which can open web pages and run exe's.

- see the general page, and the user account dialog for examples.

svn path=/trunk/; revision=24205
This commit is contained in:
Ged Murphy 2006-09-18 22:25:00 +00:00
parent d00d45c34e
commit 3f0a7fb997
7 changed files with 249 additions and 18 deletions

View file

@ -0,0 +1,209 @@
/*
* PROJECT: ReactOS System Control Panel Applet
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll/cpl/sysdm/custclicklink.c
* PURPOSE: Subclass static control to link to apps
* COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
*
*/
#include "precomp.h"
#define LINK_COLOR RGB(0,0,128)
#define MAX_PARAMS 256
typedef struct _LINKCTL
{
HWND hSelf;
WNDPROC OldProc;
TCHAR szApp[MAX_PATH];
TCHAR szParams[MAX_PARAMS];
HFONT hFont;
BOOL bClicked;
} LINKCTL, *PLINKCTL;
static VOID
DoLButtonUp(PLINKCTL pLink, LPARAM lParam)
{
ReleaseCapture();
if (pLink->bClicked)
{
POINT pt;
RECT rc;
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
ClientToScreen(pLink->hSelf, &pt);
GetWindowRect(pLink->hSelf, &rc);
if (PtInRect(&rc, pt))
{
ShellExecute(NULL,
_T("open"),
pLink->szApp,
pLink->szParams,
NULL,
SW_SHOWNORMAL);
}
pLink->bClicked = FALSE;
}
}
static VOID
DoPaint(PLINKCTL pLink, HDC hdc)
{
TCHAR szText[MAX_PATH];
DWORD WinStyle, DrawStyle;
RECT rc;
HANDLE hOld;
WinStyle = GetWindowLongPtr(pLink->hSelf, GWL_STYLE);
DrawStyle = DT_SINGLELINE;
if (WinStyle & SS_CENTER)
DrawStyle |= DT_CENTER;
if (WinStyle & SS_RIGHT)
DrawStyle |= DT_RIGHT;
if (WinStyle & SS_CENTERIMAGE)
DrawStyle |= DT_VCENTER;
SetTextColor(hdc, LINK_COLOR);
SetBkMode(hdc, TRANSPARENT);
hOld = SelectObject(hdc, pLink->hFont);
SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
GetClientRect(pLink->hSelf, &rc);
GetWindowText(pLink->hSelf, szText, sizeof(szText));
DrawText(hdc, szText, -1, &rc, DrawStyle);
}
static LRESULT CALLBACK
LinkCtlWndProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
PLINKCTL pLink = (PLINKCTL)GetWindowLongPtr(hwnd, GWL_USERDATA);
WNDPROC oldproc = pLink->OldProc;
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hwnd, &ps);
DoPaint(pLink, hdc);
EndPaint(hwnd, &ps);
return 0;
}
case WM_SETCURSOR:
{
HCURSOR hCur = LoadCursor(NULL, IDC_HAND);
SetCursor(hCur);
return TRUE;
}
case WM_SETFONT:
{
LOGFONT LogFont;
HFONT hOldFont;
hOldFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
GetObject(hOldFont, sizeof(LogFont), &LogFont);
LogFont.lfUnderline = TRUE;
if (pLink->hFont) DeleteObject(hwnd);
pLink->hFont = CreateFontIndirect(&LogFont);
CallWindowProc(pLink->OldProc, hwnd, msg, wParam, lParam);
if (LOWORD(lParam))
{
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
}
return 0;
}
case WM_NCHITTEST:
return HTCLIENT;
case WM_LBUTTONDOWN:
{
SetFocus(hwnd);
SetCapture(hwnd);
pLink->bClicked = TRUE;
}
break;
case WM_LBUTTONUP:
{
DoLButtonUp(pLink, lParam);
}
break;
case WM_NCDESTROY:
{
HeapFree(GetProcessHeap(),
0,
pLink);
}
break;
}
return CallWindowProc(oldproc,
hwnd,
msg,
wParam,
lParam);
}
BOOL
TextToLink(HWND hwnd,
LPTSTR lpApp,
LPTSTR lpParams)
{
PLINKCTL pLink;
HFONT hFont;
/* error checking */
if (lstrlen(lpApp) >= (MAX_PATH - 1) ||
lstrlen(lpParams) >= (MAX_PARAMS -1))
{
return FALSE;
}
pLink = (PLINKCTL)HeapAlloc(GetProcessHeap(),
0,
sizeof(LINKCTL));
if (pLink == NULL)
return FALSE;
pLink->hSelf = hwnd;
lstrcpyn(pLink->szApp, lpApp, MAX_PATH);
lstrcpyn(pLink->szParams, lpParams, MAX_PARAMS);
pLink->bClicked = FALSE;
hFont=(HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
pLink->OldProc = (WNDPROC)SetWindowLongPtr(hwnd,
GWL_WNDPROC,
(LONG_PTR)LinkCtlWndProc);
SetWindowLongPtr(hwnd,
GWL_USERDATA,
(LONG_PTR)pLink);
SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, 0);
return TRUE;
}

View file

@ -15,7 +15,8 @@ BEGIN
LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9
LTEXT "", IDC_PROCESSORSPEED, 130, 162, 118, 9
LTEXT "", IDC_SYSTEMMEMORY, 130, 171, 118, 9
PUSHBUTTON "View licence...", IDC_LICENCE, 90, 199, 78, 13
LTEXT "Visit the ReactOS Homepage", IDC_ROSHOMEPAGE_LINK, 20, 200, 93, 8
PUSHBUTTON "View licence...", IDC_LICENCE, 170, 199, 78, 13
END
@ -132,9 +133,9 @@ END
IDD_USERPROFILE DIALOGEX 0, 0, 256, 218
STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "User Profiles"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
FONT 8, "MS Shell Dlg"
BEGIN
ICON IDI_USERPROF, IDC_STATIC, 6, 11, 16, 16, SS_ICON
LTEXT "User profiles contain desktop settings and other information related to your login. A different profile can be created on each computer you use, or you can select a roaming profile that is the same on every computer you use.",
@ -142,15 +143,16 @@ BEGIN
LTEXT "Profiles stored on this computer:", IDC_STATIC, 16, 51, 204, 9
CONTROL "", IDC_USERPROFILE_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,
6, 66, 244, 85, WS_EX_CLIENTEDGE
PUSHBUTTON "Change Type...", IDC_USERPROFILE_CHANGE, 134, 156, 62, 13
PUSHBUTTON "Change Type", IDC_USERPROFILE_CHANGE, 90, 156, 50, 13
PUSHBUTTON "Delete", IDC_USERPROFILE_DELETE, 145, 156, 50, 13
PUSHBUTTON "Copy To", IDC_USERPROFILE_COPY, 200, 156, 50, 13
LTEXT "To create new user accounts, open ", IDC_STATIC, 10, 175, 116, 9
// FIXME: needs custom control writing
//CONTROL "", IDC_CUST_LINK, "LinkCtlProc", WS_CHILD | VS_VISIBLE | WS_TABSTOP, 127, 175, 60, 9
LTEXT "in Control Panel.", IDC_STATIC, 184, 175, 64, 9
LTEXT "To create new user accounts, open ", IDC_STATIC, 7, 175, 116, 8
LTEXT "User Accounts", IDC_USERACCOUNT_LINK, 123, 175, 48, 8
LTEXT "in Control Panel.", IDC_STATIC, 173, 175, 64, 8
DEFPUSHBUTTON "OK", IDOK, 134, 197, 54, 13
PUSHBUTTON "Cancel", IDCANCEL, 196, 197, 54, 13
DEFPUSHBUTTON "OK", IDOK, 134, 200, 54, 13
PUSHBUTTON "Cancel", IDCANCEL, 196, 200, 54, 13
END

View file

@ -95,6 +95,12 @@ GeneralPageProc(HWND hwndDlg,
{
case WM_INITDIALOG:
{
HWND hLink = GetDlgItem(hwndDlg, IDC_ROSHOMEPAGE_LINK);
TextToLink(hLink,
_T("http://www.reactos.org"),
NULL);
InitImageInfo(&ImgInfo);
GetSystemInformation(hwndDlg);
}
@ -108,6 +114,7 @@ GeneralPageProc(HWND hwndDlg,
MAKEINTRESOURCE(IDD_LICENCE),
hwndDlg,
LicenceDlgProc);
return TRUE;
}
}
@ -129,21 +136,21 @@ GeneralPageProc(HWND hwndDlg,
if (hdcMem != NULL)
{
SelectObject(hdcMem, ImgInfo.hBitmap);
BitBlt(lpDrawItem->hDC,
left,
BitBlt(lpDrawItem->hDC,
left,
lpDrawItem->rcItem.top,
lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
hdcMem,
0,
0,
hdcMem,
0,
0,
SRCCOPY);
DeleteDC(hdcMem);
}
}
return TRUE;
}
}
return FALSE;

View file

@ -39,6 +39,8 @@ INT_PTR CALLBACK StartRecDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK LicenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL TextToLink(HWND hwnd, LPTSTR lpApp, LPTSTR lpParams);
typedef struct _PAGEFILE
{
TCHAR szDrive[3];

View file

@ -21,8 +21,9 @@
#define IDC_PROCESSOR 102
#define IDC_PROCESSORSPEED 103
#define IDC_SYSTEMMEMORY 104
#define IDC_LICENCE 105
#define IDC_LICENCE 105
#define IDC_ROSIMG 106
#define IDC_ROSHOMEPAGE_LINK 107
/* propsheet - computer name */
@ -56,7 +57,9 @@
#define IDD_USERPROFILE 500
#define IDC_USERPROFILE_LIST 501
#define IDC_USERPROFILE_CHANGE 503
#define IDC_CUST_LINK 504
#define IDC_USERPROFILE_DELETE 504
#define IDC_USERPROFILE_COPY 505
#define IDC_USERACCOUNT_LINK 506
/* environment variables */

View file

@ -20,6 +20,7 @@
<library>shell32</library>
<file>advanced.c</file>
<file>computer.c</file>
<file>custclicklink.c</file>
<file>environment.c</file>
<file>general.c</file>
<file>hardprof.c</file>

View file

@ -20,10 +20,17 @@ UserProfileDlgProc(HWND hwndDlg,
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(hwndDlg);
switch(uMsg)
{
case WM_INITDIALOG:
{
HWND hLink = GetDlgItem(hwndDlg, IDC_USERACCOUNT_LINK);
TextToLink(hLink,
_T("rundll32.exe"),
_T("shell32.dll, Control_RunDLL nusrmgr.cpl"));
MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0);
}
break;