|
|
/* Copyright (c) 1995, Microsoft Corporation, all rights reserved
** ** lvx.c ** Listview extension routines ** Listed alphabetically ** ** 11/25/95 Steve Cobb ** Some adapted from \\ftp\data\softlib\mslfiles\odlistvw.exe sample code. */
#include <windows.h> // Win32 root
#include <windowsx.h> // Win32 macro extensions
#include <commctrl.h> // Win32 common controls
#include <debug.h> // Trace and assert
#include <uiutil.h> // Our public header
#include <lvx.rch> // Our resource constants
/* List view of check boxes state indices.
*/ #define SI_Unchecked 1
#define SI_Checked 2
#define SI_DisabledUnchecked 3
#define SI_DisabledChecked 4
/* Text indents within a column in pixels. If you mess with the dx, you're
** asking for misalignment problems with the header labels. BTW, the first ** column doesn't line up with it's header if there are no icons. Regular ** list view has this problem, too. If you try to fix this you'll wind up ** duplicating the AUTOSIZE_USEHEADER option of ListView_SetColumnWidth. ** Should be able to change the dy without causing problems. */ #define LVX_dxColText 4
#define LVX_dyColText 1
/* Guaranteed vertical space between icons. Should be able to mess with this
** without causing problems. */ #define LVX_dyIconSpacing 1
/* The atom identifying our context property suitable for use by the Windows
** XxxProp APIs. A Prop is used to associate context information (the address ** of the WNDPROC we subclassed) with a "list view of check boxes" window. */ static LPCWSTR g_lvxcbContextId = NULL;
/*----------------------------------------------------------------------------
** Local prototypes **---------------------------------------------------------------------------- */ LRESULT APIENTRY LvxcbProc( IN HWND hwnd, IN UINT unMsg, IN WPARAM wparam, IN LPARAM lparam );
BOOL LvxDrawItem( IN DRAWITEMSTRUCT* pdis, IN PLVXCALLBACK pLvxCallback );
BOOL LvxMeasureItem( IN HWND hwnd, IN OUT MEASUREITEMSTRUCT* pmis );
/*----------------------------------------------------------------------------
** ListView of check boxes **---------------------------------------------------------------------------- */
BOOL ListView_GetCheck( IN HWND hwndLv, IN INT iItem )
/* Returns true if the check box of item 'iItem' of listview of checkboxes
** 'hwndLv' is checked, false otherwise. This function works on disabled ** check boxes as well as enabled ones. */ { UINT unState;
unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK ); return !!((unState == INDEXTOSTATEIMAGEMASK( SI_Checked )) || (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked ))); }
BOOL ListView_IsCheckDisabled ( IN HWND hwndLv, IN INT iItem)
/* Returns true if the check box of item 'iItem' of listview of checkboxes
** 'hwndLv' is disabled, false otherwise. */ { UINT unState; unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK );
if ((unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked )) || (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledUnchecked ))) return TRUE;
return FALSE; }
VOID ListView_DisableCheck ( IN HWND hwndLv, IN INT iItem)
/* Disables a check box of item 'iItem' of listview of checkboxes. Once
** disabled, ListView_SetCheck will have no effect on the item until ** ListView_EnableCheck(...) is called for this item. Likewise, there is no ** way through the UI to change the check of this item until it is enabled. ** Calling this function on a disabled check has no effect. */ { BOOL fCheck;
fCheck = ListView_GetCheck(hwndLv, iItem); ListView_SetItemState( hwndLv, iItem, INDEXTOSTATEIMAGEMASK( (fCheck) ? SI_DisabledChecked : SI_DisabledUnchecked), LVIS_STATEIMAGEMASK ); }
VOID ListView_EnableCheck ( IN HWND hwndLv, IN INT iItem)
/* Reverses the effect of ListView_DisableCheck.
*/ { BOOL fCheck;
fCheck = ListView_GetCheck(hwndLv, iItem); ListView_SetItemState( hwndLv, iItem, INDEXTOSTATEIMAGEMASK( (fCheck) ? SI_Checked : SI_Unchecked ), LVIS_STATEIMAGEMASK ); }
UINT ListView_GetCheckedCount( IN HWND hwndLv )
/* Returns the number of checked items in 'hwndLv' regardless of whether
** they are disabled. */ { UINT c = 0; INT i = -1;
while ((i = ListView_GetNextItem( hwndLv, i, LVNI_ALL )) >= 0) { if (ListView_GetCheck( hwndLv, i )) ++c; }
return c; }
BOOL ListView_InstallChecks( IN HWND hwndLv, IN HINSTANCE hinst )
/* Initialize "list of checkbox" handling for listview 'hwndLv'. 'Hinst'
** is the module instance containing the two checkbox icons. See LVX.RC. ** ** Returns true if successful, false otherwise. Caller must eventually ** call 'ListView_UninstallChecks', typically in WM_DESTROY processing. */ { HICON hIcon; HIMAGELIST himl; WNDPROC pOldProc; //Add this for RTL(right to left, mirrored windows version)
//whistler bug 41349 gangz
//
BOOL fMirrored=FALSE; DWORD dwLayout;
// pmay: 397395
//
// Prevent endless loops resulting from accidentally calling this
// api twice.
//
pOldProc = (WNDPROC)GetWindowLongPtr(hwndLv, GWLP_WNDPROC); if (pOldProc == LvxcbProc) { return TRUE; }
//get current application's layout (RTL or normal) gangz
// for whistler bug 41349
//There are two ways:
//(1) use GetWindowLong() with GWL_EXSTYLE for WS_EX_LAYOUTRTL style if
// you have a window handler available
//(2) use GetProcessDefaultLayout() to get the layout for the current
// process, and compare that against LAYOUT_RTL
//
dwLayout = GetWindowLong(hwndLv, GWL_EXSTYLE); if ( WS_EX_LAYOUTRTL & dwLayout ) { fMirrored = TRUE; }
/* Build checkbox image lists.
*/ himl = ImageList_Create( GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), ILC_MASK, 2, 2 );
/* The order these are added is significant since it implicitly
** establishes the state indices matching SI_Unchecked and SI_Checked. */ hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Unchecked ) ); if ( NULL != hIcon ) { ImageList_AddIcon( himl, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( fMirrored?IID_CheckedRTL : IID_Checked ) ); if ( NULL != hIcon ) { ImageList_AddIcon( himl, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_DisabledUnchecked ) ); if ( NULL != hIcon ) { ImageList_AddIcon( himl, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( fMirrored?IID_DisabledCheckedRTL : IID_DisabledChecked ) ); if ( NULL != hIcon ) { ImageList_AddIcon( himl, hIcon ); DeleteObject( hIcon ); }
ListView_SetImageList( hwndLv, himl, LVSIL_STATE );
/* Register atom for use in the Windows XxxProp calls which are used to
** associate the old WNDPROC with the listview window handle. */ if (!g_lvxcbContextId) g_lvxcbContextId = (LPCWSTR )GlobalAddAtom( L"RASLVXCB" ); if (!g_lvxcbContextId) return FALSE;
/* Subclass the current window procedure.
*/ pOldProc = (WNDPROC)SetWindowLongPtr( hwndLv, GWLP_WNDPROC, (ULONG_PTR)LvxcbProc );
return SetProp( hwndLv, g_lvxcbContextId, (HANDLE )pOldProc ); }
VOID ListView_SetCheck( IN HWND hwndLv, IN INT iItem, IN BOOL fCheck )
/* Sets the check mark on item 'iItem' of listview of checkboxes 'hwndLv'
** to checked if 'fCheck' is true or unchecked if false. */ { NM_LISTVIEW nmlv;
if (ListView_IsCheckDisabled(hwndLv, iItem)) return;
ListView_SetItemState( hwndLv, iItem, INDEXTOSTATEIMAGEMASK( (fCheck) ? SI_Checked : SI_Unchecked ), LVIS_STATEIMAGEMASK );
nmlv.hdr.code = LVXN_SETCHECK; nmlv.hdr.hwndFrom = hwndLv; nmlv.iItem = iItem;
FORWARD_WM_NOTIFY( GetParent(hwndLv), GetDlgCtrlID(hwndLv), &nmlv, SendMessage ); }
VOID ListView_UninstallChecks( IN HWND hwndLv )
/* Uninstalls "listview of check boxes" handling from list view 'hwndLv'.
*/ { WNDPROC pOldProc;
pOldProc = (WNDPROC)GetProp( hwndLv, g_lvxcbContextId ); if (pOldProc) { /* Un-subclass so it can terminate without access to the context.
*/ SetWindowLongPtr( hwndLv, GWLP_WNDPROC, (ULONG_PTR)pOldProc ); }
RemoveProp( hwndLv, g_lvxcbContextId ); }
LRESULT APIENTRY LvxcbProc( IN HWND hwnd, IN UINT unMsg, IN WPARAM wparam, IN LPARAM lparam )
/* List view subclass window procedure to trap toggle-check events.
*/ { WNDPROC pOldProc; INT iItem; BOOL fSet; BOOL fClear; BOOL fToggle;
iItem = -1; fSet = fClear = fToggle = FALSE;
if (unMsg == WM_LBUTTONDOWN) { LV_HITTESTINFO info;
/* Left mouse button pressed over checkbox icon toggles state.
** Normally, we'd use LVHT_ONITEMSTATEICON and be done with it, but we ** want to work with our cool owner-drawn list view extensions in ** which case the control doesn't know where the icon is on the item, ** so it returns a hit anywhere on the item anyway. */ ZeroMemory( &info, sizeof(info) ); info.pt.x = LOWORD( lparam ); info.pt.y = HIWORD( lparam ); info.flags = LVHT_ONITEM; iItem = ListView_HitTest( hwnd, &info );
if (iItem >= 0) { /* OK, it's over item 'iItem'. Now figure out if it's over the
** checkbox. Note this currently doesn't account for use of the ** "indent" feature on an owner-drawn item. */ if ((INT )(LOWORD( lparam )) >= GetSystemMetrics( SM_CXSMICON )) iItem = -1; else fToggle = TRUE; } } else if (unMsg == WM_LBUTTONDBLCLK) { LV_HITTESTINFO info;
/* Left mouse button double clicked over any area toggles state.
** Normally, we'd use LVHT_ONITEMSTATEICON and be done with it, but we ** want to work with our cool owner-drawn list view extensions in ** which case the control doesn't know where the icon is on the item, ** so it returns a hit anywhere on the item anyway. */ ZeroMemory( &info, sizeof(info) ); info.pt.x = LOWORD( lparam ); info.pt.y = HIWORD( lparam ); info.flags = LVHT_ONITEM; iItem = ListView_HitTest( hwnd, &info );
if (iItem >= 0) { /* OK, it's over item 'iItem'. If the click does not occur
* over a checkbox, inform the parent of the double click. */ if ((INT )(LOWORD( lparam )) >= GetSystemMetrics( SM_CXSMICON )) { NM_LISTVIEW nmlv; nmlv.hdr.code = LVXN_DBLCLK; nmlv.hdr.hwndFrom = hwnd; nmlv.iItem = iItem; FORWARD_WM_NOTIFY( GetParent(hwnd), GetDlgCtrlID(hwnd), &nmlv, SendMessage); iItem = -1; }
/*
* Otherwise, toggle the state. */ else fToggle = TRUE; } } else if (unMsg == WM_CHAR) { /* Space bar pressed with item selected toggles check.
** Plus or Equals keys set check. ** Minus key clears check. */ switch (wparam) { case TEXT(' '): fToggle = TRUE; break;
case TEXT('+'): case TEXT('='): fSet = TRUE; break;
case TEXT('-'): fClear = TRUE; break; }
if (fToggle || fSet || fClear) iItem = ListView_GetNextItem( hwnd, -1, LVNI_SELECTED ); } else if (unMsg == WM_KEYDOWN) { /* Left arrow becomes up arrow and right arrow becomes down arrow so
** the list of checkboxes behaves just like a static group of ** checkboxes. */ if (wparam == VK_LEFT) wparam = VK_UP; else if (wparam == VK_RIGHT) wparam = VK_DOWN; }
if (iItem >= 0) {
/* If we are handling the spacebar, plus, minus, or equals,
** the change we make applies to all the selected items; ** hence the do {} while(WM_CHAR). */ do {
if (fToggle) { UINT unOldState; BOOL fCheck; fCheck = ListView_GetCheck( hwnd, iItem ); ListView_SetCheck( hwnd, iItem, !fCheck ); } else if (fSet) { if (!ListView_GetCheck( hwnd, iItem )) ListView_SetCheck( hwnd, iItem, TRUE ); } else if (fClear) { if (ListView_GetCheck( hwnd, iItem )) ListView_SetCheck( hwnd, iItem, FALSE ); }
iItem = ListView_GetNextItem(hwnd, iItem, LVNI_SELECTED);
} while(iItem >= 0 && unMsg == WM_CHAR);
if (fSet || fClear) {
/* Don't pass to listview to avoid beep.
*/ return 0; } }
pOldProc = (WNDPROC )GetProp( hwnd, g_lvxcbContextId ); if (pOldProc) return CallWindowProc( pOldProc, hwnd, unMsg, wparam, lparam );
return 0; }
/*----------------------------------------------------------------------------
** Enhanced ListView **---------------------------------------------------------------------------- */
BOOL ListView_OwnerHandler( IN HWND hwnd, IN UINT unMsg, IN WPARAM wparam, IN LPARAM lparam, IN PLVXCALLBACK pLvxCallback )
/* Handler that, when installed, turns a regular report-view-only list
** view (but with style LVS_OWNERDRAWFIXED) into an enhanced list view ** with full width selection bar and other custom column display options. ** It should appear in list view owner's dialog proc as follows: ** ** BOOL ** MyDlgProc( ** IN HWND hwnd, ** IN UINT unMsg, ** IN WPARAM wparam, ** IN LPARAM lparam ) ** { ** if (ListView_OwnerHandler( ** hwnd, unMsg, wParam, lParam, MyLvxCallback )) ** return TRUE; ** ** <the rest of your stuff here> ** } ** ** 'PLvxCallback' is caller's callback routine that provides information ** about drawing columns and other options. ** ** Returns true if processed message, false otherwise. */ { /* This routine executes on EVERY message thru the dialog so keep it
** efficient, please. */ switch (unMsg) { case WM_DRAWITEM: return LvxDrawItem( (DRAWITEMSTRUCT* )lparam, pLvxCallback );
case WM_MEASUREITEM: return LvxMeasureItem( hwnd, (MEASUREITEMSTRUCT* )lparam ); }
return FALSE; }
BOOL LvxDrawItem( IN DRAWITEMSTRUCT* pdis, IN PLVXCALLBACK pLvxCallback )
/* Respond to WM_DRAWITEM by drawing the list view item. 'Pdis' is the
** information sent by the system. 'PLvxCallback' is caller's callback to ** get information about drawing the control. ** ** Returns true is processed the message, false otherwise. */ { LV_ITEM item; INT i; INT dxState; INT dyState; INT dxSmall; INT dySmall; INT dxIndent; UINT uiStyleState; UINT uiStyleSmall; HIMAGELIST himlState; HIMAGELIST himlSmall; LVXDRAWINFO* pDrawInfo; RECT rc; RECT rcClient; BOOL fEnabled; BOOL fSelected; HDC hdc; HFONT hfont;
TRACE3("LvxDrawItem,i=%d,a=$%X,s=$%X", pdis->itemID,pdis->itemAction,pdis->itemState);
/* Make sure this is something we want to handle.
*/ if (pdis->CtlType != ODT_LISTVIEW) return FALSE;
if (pdis->itemAction != ODA_DRAWENTIRE && pdis->itemAction != ODA_SELECT && pdis->itemAction != ODA_FOCUS) { return TRUE; }
/* Get item information from the list view.
*/ ZeroMemory( &item, sizeof(item) ); item.mask = LVIF_IMAGE + LVIF_STATE; item.iItem = pdis->itemID; item.stateMask = LVIS_STATEIMAGEMASK; if (!ListView_GetItem( pdis->hwndItem, &item )) { TRACE("LvxDrawItem GetItem failed"); return TRUE; }
/* Stash some useful stuff for reference later.
*/ fEnabled = IsWindowEnabled( pdis->hwndItem ) && !(pdis->itemState & ODS_DISABLED); fSelected = (pdis->itemState & ODS_SELECTED); GetClientRect( pdis->hwndItem, &rcClient );
/* Callback owner to get drawing information.
*/ ASSERT(pLvxCallback); pDrawInfo = pLvxCallback( pdis->hwndItem, pdis->itemID ); ASSERT(pDrawInfo);
/* Get image list icon sizes now, though we draw them last because their
** background is set up during first column text output. */ dxState = dyState = 0; himlState = ListView_GetImageList( pdis->hwndItem, LVSIL_STATE ); if (himlState) ImageList_GetIconSize( himlState, &dxState, &dyState );
dxSmall = dySmall = 0; himlSmall = ListView_GetImageList( pdis->hwndItem, LVSIL_SMALL ); if (himlSmall) ImageList_GetIconSize( himlSmall, &dxSmall, &dySmall );
uiStyleState = uiStyleSmall = ILD_TRANSPARENT;
/* Figure out the number of pixels to indent the item, if any.
*/ if (pDrawInfo->dxIndent >= 0) dxIndent = pDrawInfo->dxIndent; else { if (dxSmall > 0) dxIndent = dxSmall; else dxIndent = GetSystemMetrics( SM_CXSMICON ); }
/* Get a device context for the window and set it up with the font the
** control says it's using. (Can't use the one that comes in the ** DRAWITEMSTRUCT because sometimes it has the wrong rectangle, see bug ** 13106) */ hdc = GetDC( pdis->hwndItem );
if(NULL == hdc) { return FALSE; } hfont = (HFONT )SendMessage( pdis->hwndItem, WM_GETFONT, 0, 0 ); if (hfont) SelectObject( hdc, hfont );
/* Set things up as if we'd just got done processing a column that ends
** after the icons, then loop thru each column from left to right. */ rc.right = pdis->rcItem.left + dxIndent + dxState + dxSmall; rc.top = pdis->rcItem.top; rc.bottom = pdis->rcItem.bottom;
for (i = 0; i < pDrawInfo->cCols; ++i) { TCHAR szText[ LVX_MaxColTchars + 1 ]; TCHAR* pszText; INT dxCol;
/* Get the column width, adding any index and icon width to the first
** column. */ // For whistler bug 458513 39081
//
ZeroMemory(szText,sizeof(szText)); dxCol = ListView_GetColumnWidth( pdis->hwndItem, i ); if (i == 0) dxCol -= dxIndent + dxState + dxSmall;
szText[ 0 ] = TEXT('\0'); ListView_GetItemText( pdis->hwndItem, pdis->itemID, i, szText, LVX_MaxColTchars + 1 );
/* Update rectangle to enclose just this one item's column 'i'.
*/ rc.left = rc.right; rc.right = rc.left + dxCol;
if ((pDrawInfo->dwFlags & LVXDI_DxFill) && i == pDrawInfo->cCols - 1) { INT dxWnd = pdis->rcItem.left + rcClient.right;
if (rc.right < dxWnd) { /* When the last column does not fill out a full controls
** width of space, extend it to the right so it does. Note ** this does not mean the user can't scroll off to the right ** if they want. ** (Abolade-Gbadegesin 03-27-96) ** Don't subtrace rc.left when there is only one column; ** this accounts for the space needed for icons. */ rc.right = pdis->rcItem.right = dxWnd; if (i == 0) { ListView_SetColumnWidth(pdis->hwndItem, i, rc.right); } else { ListView_SetColumnWidth( pdis->hwndItem, i, rc.right - rc.left ); } } }
/* Lop the text and append "..." if it won't fit in the column.
*/ pszText = Ellipsisize( hdc, szText, rc.right - rc.left, LVX_dxColText ); if (!pszText) continue;
/* Figure out the appropriate text and background colors for the
** current item state. */ if (fEnabled) { if (fSelected) { SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) ); if (pDrawInfo->dwFlags & LVXDI_Blend50Sel) uiStyleSmall |= ILD_BLEND50; } else { if (pDrawInfo->adwFlags[ i ] & LVXDIA_3dFace) { SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_3DFACE ) ); } else { SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_WINDOW ) ); } } } else { if (pDrawInfo->adwFlags[ i ] & LVXDIA_Static) { SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_3DFACE ) ); } else { SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_3DFACE ) ); }
if (pDrawInfo->dwFlags & LVXDI_Blend50Dis) uiStyleSmall |= ILD_BLEND50; }
/* Draw the column text. In the first column the background of any
** indent and icons is erased to the text background color. */ { RECT rcBg = rc;
if (i == 0) rcBg.left -= dxIndent + dxState + dxSmall;
ExtTextOut( hdc, rc.left + LVX_dxColText, rc.top + LVX_dyColText, ETO_CLIPPED + ETO_OPAQUE, &rcBg, pszText, lstrlen( pszText ), NULL ); }
Free( pszText ); }
/* Finally, draw the icons, if caller specified any.
*/ if (himlState) { ImageList_Draw( himlState, (item.state >> 12) - 1, hdc, pdis->rcItem.left + dxIndent, pdis->rcItem.top, uiStyleState ); }
if (himlSmall) { ImageList_Draw( himlSmall, item.iImage, hdc, pdis->rcItem.left + dxIndent + dxState, pdis->rcItem.top, uiStyleSmall ); }
/* Draw the dotted focus rectangle around the whole item, if indicated.
*/ //comment for bug 52688 whistler
// if ((pdis->itemState & ODS_FOCUS) && GetFocus() == pdis->hwndItem)
// DrawFocusRect( hdc, &pdis->rcItem );
//
ReleaseDC( pdis->hwndItem, hdc );
return TRUE; }
BOOL LvxMeasureItem( IN HWND hwnd, IN OUT MEASUREITEMSTRUCT* pmis )
/* Respond to WM_MEASUREITEM message, i.e. fill in the height of an item
** in the ListView. 'Hwnd' is the owner window. 'Pmis' is the structure ** provided from Windows. ** ** Returns true is processed the message, false otherwise. */ { HDC hdc; HWND hwndLv; HFONT hfont; TEXTMETRIC tm; UINT dySmIcon; RECT rc;
TRACE("LvxMeasureItem");
if (pmis->CtlType != ODT_LISTVIEW) return FALSE;
hwndLv = GetDlgItem( hwnd, pmis->CtlID ); ASSERT(hwndLv);
/* Get a device context for the list view control and set up the font the
** control says it's using. MSDN claims the final font may not be ** available at this point, but it sure seems to be. */ hdc = GetDC( hwndLv ); hfont = (HFONT )SendMessage( hwndLv, WM_GETFONT, 0, 0 ); if (hfont) SelectObject( hdc, hfont );
if (GetTextMetrics( hdc, &tm )) pmis->itemHeight = tm.tmHeight + 1; else pmis->itemHeight = 0;
/* Make sure it's tall enough for a standard small icon.
*/ dySmIcon = (UINT )GetSystemMetrics( SM_CYSMICON ); if (pmis->itemHeight < dySmIcon + LVX_dyIconSpacing) pmis->itemHeight = dySmIcon + LVX_dyIconSpacing;
/* Set the width since the docs say to, though I don't think it's used by
** list view. */ GetClientRect( hwndLv, &rc ); pmis->itemWidth = rc.right - rc.left - 1;
ReleaseDC( hwndLv, hdc ); return TRUE; }
/*----------------------------------------------------------------------------
** ListView utilities **---------------------------------------------------------------------------- */
VOID ListView_SetDeviceImageList( IN HWND hwndLv, IN HINSTANCE hinst )
/* Set the "small icon" image list view 'hwndLv' to be a list of DI_*
** images. 'Hinst' is the module instance containing the icons IID_Modem ** and IID_Adapter. For example, see RASDLG.DLL. */ { HICON hIcon; HIMAGELIST himl;
himl = ImageList_Create( GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), ILC_MASK, 2, 2 );
/* The order these are added is significant since it implicitly
** establishes the state indices matching SI_Unchecked and SI_Checked. */ hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Modem ) ); if ( NULL != hIcon ) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Adapter ) ); if ( NULL != hIcon ) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Direct_Connect ) ); if ( NULL != hIcon ) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Connections_Modem ) ); if ( NULL != hIcon ) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
ListView_SetImageList( hwndLv, himl, LVSIL_SMALL ); }
VOID ListView_SetUserImageList( IN HWND hwndLv, IN HINSTANCE hinst )
/* Set the "small icon" image list view 'hwndLv' to be a list of DI_*
** images. 'Hinst' is the module instance containing the icons IID_Modem ** and IID_Adapter. For example, see RASDLG.DLL. */ { HICON hIcon; HIMAGELIST himl;
himl = ImageList_Create( GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), ILC_MASK, 2, 2 );
/* The order these are added is significant since it implicitly
** establishes the state indices matching SI_Unchecked and SI_Checked. */ hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Connections_User ) );
if(NULL != hIcon) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
ListView_SetImageList( hwndLv, himl, LVSIL_SMALL ); }
VOID ListView_SetNetworkComponentImageList( IN HWND hwndLv, IN HINSTANCE hinst )
/* Set the "small icon" image list view 'hwndLv' to be a list of DI_*
** images. 'Hinst' is the module instance containing the icons IID_Modem ** and IID_Adapter. For example, see RASDLG.DLL. */ { HICON hIcon; HIMAGELIST himl;
himl = ImageList_Create( GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), ILC_MASK, 2, 2 );
/* The order these are added is significant since it implicitly
** establishes the state indices matching SI_Unchecked and SI_Checked. */ hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Protocol ) );
if(NULL != hIcon) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Service ) );
if(NULL != hIcon) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
hIcon = LoadIcon( hinst, MAKEINTRESOURCE( IID_Client ) );
if(NULL != hIcon) { ImageList_ReplaceIcon( himl, -1, hIcon ); DeleteObject( hIcon ); }
ListView_SetImageList( hwndLv, himl, LVSIL_SMALL ); }
|