#include "wine/debug.h"
#include "cpl.h"
#include "wine/unicode.h"
+#include "commctrl.h"
#define NO_SHLWAPI_REG
#include "shlwapi.h"
LoadStringW(applet->hModule, info.idInfo,
applet->info[i].szInfo, sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
+ /* some broken control panels seem to return incorrect values in CPL_INQUIRE,
+ but proper data in CPL_NEWINQUIRE. if we get an empty string or a null
+ icon, see what we can get from CPL_NEWINQUIRE */
+
+ if ((applet->info[i].szName == 0) || (lstrlenW(applet->info[i].szName) == 0))
+ info.idName = CPL_DYNAMIC_RES;
+
+ /* zero-length szInfo may not be a buggy applet, but it doesn't hurt for us
+ to check anyway */
+
+ if ((applet->info[i].szInfo == 0) || (lstrlenW(applet->info[i].szInfo) == 0))
+ info.idInfo = CPL_DYNAMIC_RES;
+
+ if (applet->info[i].hIcon == NULL)
+ info.idIcon = CPL_DYNAMIC_RES;
+
if ((info.idIcon == CPL_DYNAMIC_RES) || (info.idName == CPL_DYNAMIC_RES) ||
(info.idInfo == CPL_DYNAMIC_RES)) {
applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo);
return NULL;
}
+#define IDC_LISTVIEW 1000
+#define IDC_STATUSBAR 1001
+
+#define NUM_COLUMNS 2
+#define LISTVIEW_DEFSTYLE (WS_CHILD | WS_VISIBLE | WS_TABSTOP |\
+ LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_SINGLESEL)
+
+static BOOL Control_CreateListView (CPanel *panel)
+{
+ RECT ws, sb;
+ WCHAR empty_string[] = {0};
+ WCHAR buf[MAX_STRING_LEN];
+ LVCOLUMNW lvc;
+
+ /* Create list view */
+ GetClientRect(panel->hWndStatusBar, &sb);
+ GetClientRect(panel->hWnd, &ws);
+
+ panel->hWndListView = CreateWindowExW(WS_EX_CLIENTEDGE, WC_LISTVIEWW,
+ empty_string, LISTVIEW_DEFSTYLE | LVS_ICON,
+ 0, 0, ws.right - ws.left, ws.bottom - ws.top -
+ (sb.bottom - sb.top), panel->hWnd,
+ (HMENU) IDC_LISTVIEW, panel->hInst, NULL);
+
+ if (!panel->hWndListView)
+ return FALSE;
+
+ /* Create image lists for list view */
+ panel->hImageListSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON), ILC_MASK, 1, 1);
+ panel->hImageListLarge = ImageList_Create(GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON), ILC_MASK, 1, 1);
+
+ (void) ListView_SetImageList(panel->hWndListView, panel->hImageListSmall, LVSIL_SMALL);
+ (void) ListView_SetImageList(panel->hWndListView, panel->hImageListLarge, LVSIL_NORMAL);
+
+ /* Create columns for list view */
+ lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
+ lvc.pszText = buf;
+ lvc.fmt = LVCFMT_LEFT;
+
+ /* Name column */
+ lvc.iSubItem = 0;
+ lvc.cx = (ws.right - ws.left) / 3;
+ LoadStringW(shell32_hInstance, IDS_CPANEL_NAME, buf, sizeof(buf) / sizeof(buf[0]));
+
+ if (ListView_InsertColumnW(panel->hWndListView, 0, &lvc) == -1)
+ return FALSE;
+
+ /* Description column */
+ lvc.iSubItem = 1;
+ lvc.cx = ((ws.right - ws.left) / 3) * 2;
+ LoadStringW(shell32_hInstance, IDS_CPANEL_DESCRIPTION, buf, sizeof(buf) /
+ sizeof(buf[0]));
+
+ if (ListView_InsertColumnW(panel->hWndListView, 1, &lvc) == -1)
+ return FALSE;
+
+ return(TRUE);
+}
+
static void Control_WndProc_Create(HWND hWnd, const CREATESTRUCTW* cs)
{
CPanel* panel = (CPanel*)cs->lpCreateParams;
HMENU hMenu, hSubMenu;
CPlApplet* applet;
MENUITEMINFOW mii;
- int menucount, i;
+ unsigned int i;
+ int menucount, index;
CPlItem *item;
+ LVITEMW lvItem;
+ INITCOMMONCONTROLSEX icex;
+ INT sb_parts;
+ int itemidx;
SetWindowLongPtrW(hWnd, 0, (LONG_PTR)panel);
panel->hWnd = hWnd;
+ /* Initialise common control DLL */
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ /* create the status bar */
+ if (!(panel->hWndStatusBar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, NULL, hWnd, IDC_STATUSBAR)))
+ return;
+
+ sb_parts = -1;
+ SendMessageW(panel->hWndStatusBar, SB_SETPARTS, 1, (LPARAM) &sb_parts);
+
+ /* create the list view */
+ if (!Control_CreateListView(panel))
+ return;
+
hMenu = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(MENU_CPANEL));
/* insert menu items for applets */
mii.dwTypeData = applet->info[i].szName;
mii.cch = sizeof(applet->info[i].szName) / sizeof(applet->info[i].szName[0]);
mii.wID = IDM_CPANEL_APPLET_BASE + menucount;
- mii.dwItemData = (DWORD) item;
+ mii.dwItemData = (ULONG_PTR)item;
if (InsertMenuItemW(hSubMenu, menucount, TRUE, &mii)) {
- DrawMenuBar(hWnd);
- menucount++;
+ /* add the list view item */
+ index = ImageList_AddIcon(panel->hImageListLarge, applet->info[i].hIcon);
+ ImageList_AddIcon(panel->hImageListSmall, applet->info[i].hIcon);
+
+ lvItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
+ lvItem.iItem = menucount;
+ lvItem.iSubItem = 0;
+ lvItem.pszText = applet->info[i].szName;
+ lvItem.iImage = index;
+ lvItem.lParam = (LPARAM) item;
+
+ itemidx = ListView_InsertItemW(panel->hWndListView, &lvItem);
+
+ /* add the description */
+ ListView_SetItemTextW(panel->hWndListView, itemidx, 1,
+ applet->info[i].szInfo);
+
+ /* update menu bar, increment count */
+ DrawMenuBar(hWnd);
+ menucount++;
}
}
}
{
HMENU hMenu, hSubMenu;
MENUITEMINFOW mii;
- int i;
+ unsigned int i;
/* get the File menu */
hMenu = GetMenu(hWnd);
}
}
+static void Control_UpdateListViewStyle(CPanel *panel, UINT style, UINT id)
+{
+ HMENU hMenu, hSubMenu;
+
+ SetWindowLongW(panel->hWndListView, GWL_STYLE, LISTVIEW_DEFSTYLE | style);
+
+ /* update the menu */
+ hMenu = GetMenu(panel->hWnd);
+ hSubMenu = GetSubMenu(hMenu, 1);
+
+ CheckMenuRadioItem(hSubMenu, FCIDM_SHVIEW_BIGICON, FCIDM_SHVIEW_REPORTVIEW,
+ id, MF_BYCOMMAND);
+}
+
+static CPlItem* Control_GetCPlItem_From_MenuID(HWND hWnd, UINT id)
+{
+ HMENU hMenu, hSubMenu;
+ MENUITEMINFOW mii;
+
+ /* retrieve the CPlItem structure from the menu item data */
+ hMenu = GetMenu(hWnd);
+
+ if (!hMenu)
+ return NULL;
+
+ hSubMenu = GetSubMenu(hMenu, 0);
+
+ if (!hSubMenu)
+ return NULL;
+
+ mii.cbSize = sizeof(MENUITEMINFOW);
+ mii.fMask = MIIM_DATA;
+
+ if (!GetMenuItemInfoW(hSubMenu, id, FALSE, &mii))
+ return NULL;
+
+ return (CPlItem *) mii.dwItemData;
+}
+
+static CPlItem* Control_GetCPlItem_From_ListView(CPanel *panel)
+{
+ LVITEMW lvItem;
+ int selitem;
+
+ selitem = SendMessageW(panel->hWndListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
+ | LVNI_SELECTED);
+
+ if (selitem != -1)
+ {
+ lvItem.iItem = selitem;
+ lvItem.mask = LVIF_PARAM;
+
+ if (SendMessageW(panel->hWndListView, LVM_GETITEMW, 0, (LPARAM) &lvItem))
+ return (CPlItem *) lvItem.lParam;
+ }
+
+ return NULL;
+}
+
static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg,
WPARAM lParam1, LPARAM lParam2)
{
}
case FCIDM_SHVIEW_BIGICON:
+ Control_UpdateListViewStyle(panel, LVS_ICON, FCIDM_SHVIEW_BIGICON);
+ return 0;
+
case FCIDM_SHVIEW_SMALLICON:
+ Control_UpdateListViewStyle(panel, LVS_SMALLICON, FCIDM_SHVIEW_SMALLICON);
+ return 0;
+
case FCIDM_SHVIEW_LISTVIEW:
+ Control_UpdateListViewStyle(panel, LVS_LIST, FCIDM_SHVIEW_LISTVIEW);
+ return 0;
+
case FCIDM_SHVIEW_REPORTVIEW:
+ Control_UpdateListViewStyle(panel, LVS_REPORT, FCIDM_SHVIEW_REPORTVIEW);
return 0;
default:
if ((LOWORD(lParam1) >= IDM_CPANEL_APPLET_BASE) &&
(LOWORD(lParam1) <= IDM_CPANEL_APPLET_BASE + panel->total_subprogs))
{
- CPlItem *item;
- HMENU hMenu, hSubMenu;
- MENUITEMINFOW mii;
-
- /* retrieve the CPlItem structure from the menu item data */
- hMenu = GetMenu(hWnd);
-
- if (!hMenu)
- break;
-
- hSubMenu = GetSubMenu(hMenu, 0);
-
- if (!hSubMenu)
- break;
-
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_DATA;
-
- if (!GetMenuItemInfoW(hSubMenu, LOWORD(lParam1), FALSE, &mii))
- break;
-
- item = (CPlItem *) mii.dwItemData;
+ CPlItem *item = Control_GetCPlItem_From_MenuID(hWnd, LOWORD(lParam1));
/* execute the applet if item is valid */
if (item)
}
break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR nmh = (LPNMHDR) lParam2;
+
+ switch (nmh->idFrom)
+ {
+ case IDC_LISTVIEW:
+ switch (nmh->code)
+ {
+ case NM_RETURN:
+ case NM_DBLCLK:
+ {
+ CPlItem *item = Control_GetCPlItem_From_ListView(panel);
+
+ /* execute the applet if item is valid */
+ if (item)
+ item->applet->proc(item->applet->hWnd, CPL_DBLCLK,
+ item->id, item->applet->info[item->id].lData);
+
+ return 0;
+ }
+ case LVN_ITEMCHANGED:
+ {
+ CPlItem *item = Control_GetCPlItem_From_ListView(panel);
+
+ /* update the status bar if item is valid */
+ if (item)
+ SetWindowTextW(panel->hWndStatusBar,
+ item->applet->info[item->id].szInfo);
+ else
+ SetWindowTextW(panel->hWndStatusBar, NULL);
+
+ return 0;
+ }
+ }
+
+ break;
+ }
+
+ break;
+ }
+
+ case WM_MENUSELECT:
+ /* check if this is an applet */
+ if ((LOWORD(lParam1) >= IDM_CPANEL_APPLET_BASE) &&
+ (LOWORD(lParam1) <= IDM_CPANEL_APPLET_BASE + panel->total_subprogs))
+ {
+ CPlItem *item = Control_GetCPlItem_From_MenuID(hWnd, LOWORD(lParam1));
+
+ /* update the status bar if item is valid */
+ if (item)
+ SetWindowTextW(panel->hWndStatusBar, item->applet->info[item->id].szInfo);
+ }
+ else if ((HIWORD(lParam1) == 0xFFFF) && (lParam2 == 0))
+ {
+ /* reset status bar description to that of the selected icon */
+ CPlItem *item = Control_GetCPlItem_From_ListView(panel);
+
+ if (item)
+ SetWindowTextW(panel->hWndStatusBar, item->applet->info[item->id].szInfo);
+ else
+ SetWindowTextW(panel->hWndStatusBar, NULL);
+
+ return 0;
+ }
+ else
+ SetWindowTextW(panel->hWndStatusBar, NULL);
+
+ return 0;
+
+ case WM_SIZE:
+ {
+ HDWP hdwp;
+ RECT sb;
+
+ hdwp = BeginDeferWindowPos(2);
+
+ if (hdwp == NULL)
+ break;
+
+ GetClientRect(panel->hWndStatusBar, &sb);
+
+ hdwp = DeferWindowPos(hdwp, panel->hWndListView, NULL, 0, 0,
+ LOWORD(lParam2), HIWORD(lParam2) - (sb.bottom - sb.top),
+ SWP_NOZORDER | SWP_NOMOVE);
+
+ if (hdwp == NULL)
+ break;
+
+ hdwp = DeferWindowPos(hdwp, panel->hWndStatusBar, NULL, 0, 0,
+ LOWORD(lParam2), LOWORD(lParam1), SWP_NOZORDER | SWP_NOMOVE);
+
+ if (hdwp != NULL)
+ EndDeferWindowPos(hdwp);
+
+ return 0;
}
+ }
}
return DefWindowProcW(hWnd, wMsg, lParam1, lParam2);
wc.lpfnWndProc = Control_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CPlApplet*);
- wc.hInstance = hInst;
+ wc.hInstance = panel->hInst = hInst;
wc.hIcon = 0;
wc.hCursor = LoadCursorW( 0, (LPWSTR)IDC_ARROW );
wc.hbrBackground = GetStockObject(WHITE_BRUSH);