📄 browser.c
字号:
// BROWSER.C
// Stefano Maruzzi 1995
// LIST16-xx
#include <windows.h>
#include <win32BK.h>
#include <windowsx.h>
#include <commctrl.h>
#include <shlobj.h>
#include "globals.h"
#include "resource.h"
#include "treeview.h"
#include "listview.h"
// function prototypes
HWND CreateTreeView(HWND hwndParent, HINSTANCE hInstance, int iID, DWORD dwStyle) ;
HWND WINAPI CreateListView(HWND hwndParent, HINSTANCE hInstance) ;
void FillTreeView( HWND hwndTreeView, LPSHELLFOLDER lpsf, LPITEMIDLIST lpiFullQualified, HTREEITEM hParent) ;
BOOL PopulateListView( HWND hwndLV, LPTVITEMDATA lptvid, LPSHELLFOLDER lpsf) ;
BOOL GetName( LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName) ;
void SwitchView( HWND hwndLV, DWORD dwView) ;
LPITEMIDLIST GetFullyQualPidl( LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) ;
LPDROPSOURCE CreateDropSource( void) ;
LRESULT DispDefault( EDWP, HWND, UINT, WPARAM, LPARAM) ;
BOOL GetName( LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName) ;
int GetIcon( LPITEMIDLIST lpi, UINT uFlags) ;
LPITEMIDLIST ConcatPidls( LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) ;
LPITEMIDLIST CopyITEMID( LPMALLOC lpMalloc, LPITEMIDLIST lpi) ;
LPITEMIDLIST ConcatPidls( LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) ;
LPITEMIDLIST GetFullyQualPidl( LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) ;
LPITEMIDLIST CopyITEMID( LPMALLOC lpMalloc, LPITEMIDLIST lpi) ;
LRESULT WINAPI WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ;
BOOL DoTheMenuThing( HWND hwnd, LPSHELLFOLDER lpsfParent, LPITEMIDLIST lpi, LPPOINT lppt) ;
LRESULT WINAPI WndProc( HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
static HINSTANCE hInstance ;
static HWND hwndTreeView ;
static HWND hwndLV ;
static int cxSplitter ;
static BOOL bOutaHere = FALSE ;
static RECT rcSplit ;
static HDC hdcSplit = NULL ;
switch( msg)
{
case WM_CREATE:
{
// Save this value for later
cxSplitter = GetSystemMetrics(SM_CXEDGE) ;
if( !cxSplitter)
cxSplitter = 2;
hwndLV = CreateListView(hwnd, hInstance) ;
// Post a message to fill the control, or nix app if the creation failed.
if( !hwndTreeView || !hwndLV)
PostMessage(hwndTreeView, WM_COMMAND, MN_EXIT, 0 ) ;
else
PostMessage( hwndTreeView, WM_COMMAND, MN_FILL, 0 ) ;
}
break ;
case WM_LBUTTONDOWN:
{
#define xPos ((int)(short)LOWORD(lParam))
SetCapture(hwnd) ;
GetClientRect(hwnd, &rcSplit) ;
// Calculate initial position
rcSplit.left = min(max(50, xPos - cxSplitter/2), rcSplit.right - 50) + 1;
// Get a DC (also used as a flag indicating we have capture)
if( hdcSplit)
ReleaseDC( hwnd, hdcSplit) ;
hdcSplit = GetDC( hwnd) ;
// draw splitter bar in initial position
PatBlt( hdcSplit, rcSplit.left, 0, cxSplitter, rcSplit.bottom, DSTINVERT) ;
}
break ;
case WM_NOTIFY:
{
POINT pt;
NM_TREEVIEW *pnmtv = (NM_TREEVIEW *)lParam;
NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lParam;
TV_HITTESTINFO tvhti ;
LV_HITTESTINFO lvhti ;
LPTVITEMDATA lptvid ;
LPLVITEMDATA lplvid ;
LPDATAOBJECT lpdo ;
HRESULT hr ;
LPMALLOC lpMalloc ;
LPSHELLFOLDER lpsf2 = 0 ;
TV_ITEM tvi ;
LV_ITEM lvi ;
DWORD dwEffect ;
static char szBuff[ MAX_PATH] ;
switch( pnmtv -> hdr.idFrom)
{
case TVN_SELCHANGED:
{
// do this only if we are not exiting the application...
if( !bOutaHere)
{
lptvid = (LPTVITEMDATA)pnmtv -> itemNew.lParam;
hr = lptvid -> lpsfParent -> lpVtbl -> BindToObject( lptvid -> lpsfParent,
lptvid -> lpi,
0,
&IID_IShellFolder,
(LPVOID *)&lpsf2) ;
if( SUCCEEDED(hr))
{
PopulateListView( hwndLV, lptvid, lpsf2) ;
lpsf2 -> lpVtbl -> Release( lpsf2) ;
}
}
}
break ;
case TVN_ITEMEXPANDING:
{
if( ( pnmtv -> itemNew.state & TVIS_EXPANDEDONCE))
break ;
lptvid = (LPTVITEMDATA)pnmtv -> itemNew.lParam ;
hr=lptvid -> lpsfParent -> lpVtbl -> BindToObject(lptvid -> lpsfParent,
lptvid -> lpi,
0,
&IID_IShellFolder,
(LPVOID *)&lpsf2) ;
if( SUCCEEDED(hr))
{
FillTreeView(hwndTreeView,
lpsf2,
lptvid -> lpifq,
pnmtv -> itemNew.hItem) ;
}
TreeView_SortChildren(hwndTreeView, pnmtv -> itemNew.hItem, FALSE) ;
}
break;
default:
break;
}
break ;
case IDD_LISTVIEW:
switch( pnmlv -> hdr.code)
{
case NM_RCLICK:
case NM_DBLCLK:
GetCursorPos((LPPOINT)&pt) ;
ScreenToClient(hwndLV, &pt) ;
lvhti.pt=pt;
ListView_HitTest(hwndLV, &lvhti) ;
if( lvhti.flags & LVHT_ONITEM)
{
ClientToScreen(hwndLV, &pt) ;
lvi.mask = LVIF_PARAM;
lvi.iItem = lvhti.iItem;
lvi.iSubItem = 0;
if( !ListView_GetItem(hwndLV, &lvi))
return 0;
lplvid=(LPLVITEMDATA)lvi.lParam;
if( pnmlv -> hdr.code==NM_RCLICK)
DoTheMenuThing(hwnd, lplvid -> lpsfParent, lplvid -> lpi, &pt) ;
else
{
if( !(lplvid -> ulAttribs & SFGAO_FOLDER))
{
SHELLEXECUTEINFO sei =
{
sizeof(SHELLEXECUTEINFO),
SEE_MASK_INVOKEIDLIST, // fMask
hwnd, // hwnd of parent
"Open", // lpVerb
NULL, // lpFile
"",
"", // lpDirectory
SW_SHOWNORMAL, // nShow
hInstance, // hInstApp
(LPVOID)NULL, // lpIDList...will set below
NULL, // lpClass
0, // hkeyClass
0, // dwHotKey
NULL // hIcon
};
sei.lpIDList=GetFullyQualPidl(lplvid -> lpsfParent, lplvid -> lpi) ;
ShellExecuteEx(&sei) ;
}
else
{
MessageBox(hwnd, "Clicked on folder", "ENUMDESK", MB_OK) ;
}
}
}
break;
case LVN_DELETEITEM:
// let's free the memory for the ListView item data...
hr=SHGetMalloc(&lpMalloc) ;
if( FAILED(hr))
break;
lvi.mask = LVIF_PARAM;
lvi.iItem = pnmlv -> iItem;
lvi.iSubItem = 0;
if( !ListView_GetItem(hwndLV, &lvi))
return 0;
lplvid=(LPLVITEMDATA)lvi.lParam;
lplvid -> lpsfParent -> lpVtbl -> Release(lplvid -> lpsfParent) ;
lpMalloc -> lpVtbl -> Free(lpMalloc, lplvid -> lpi) ;
lpMalloc -> lpVtbl -> Free(lpMalloc, lplvid) ;
lpMalloc -> lpVtbl -> Release(lpMalloc) ;
break;
default:
break;
}
break;
default:
break;
}
case WM_MOUSEMOVE:
{
int cx = (int)LOWORD( lParam) ;
if( hdcSplit)
{
// Erase previous bar
PatBlt( hdcSplit, rcSplit.left, 0, cxSplitter, rcSplit.bottom, DSTINVERT) ;
// Calculate new position
rcSplit.left = min( max( 50, cx - cxSplitter / 2), rcSplit.right - 50) + 1 ;
// Draw bar in new position
PatBlt(hdcSplit, rcSplit.left, 0, cxSplitter, rcSplit.bottom, DSTINVERT) ;
}
}
break ;
case WM_LBUTTONUP:
{
int cx = ((int)(short)LOWORD( lParam)) ;
if( hdcSplit)
{
// Erase previous bar
PatBlt( hdcSplit, rcSplit.left, 0, cxSplitter, rcSplit.bottom, DSTINVERT) ;
// Calculate new position
rcSplit.left = min( max( 50, cx - cxSplitter / 2), rcSplit.right - 50) + 1 ;
// Clean up
ReleaseCapture() ;
ReleaseDC( hwnd, hdcSplit) ;
hdcSplit = NULL ;
rcSplit.left -= cxSplitter / 2 ;
if( hwndTreeView)
SetWindowPos( hwndTreeView, HWND_TOP,
0, 0,
rcSplit.left, rcSplit.bottom,
SWP_NOZORDER) ;
rcSplit.left += cxSplitter ;
if( hwndLV)
SetWindowPos( hwndLV, HWND_TOP,
rcSplit.left, 0,
rcSplit.right - rcSplit.left, rcSplit.bottom,
SWP_NOZORDER) ;
}
}
break ;
case WM_COMMAND:
switch( LOWORD( wParam))
{
case MN_FILL:
{
LPSHELLFOLDER lpsf = 0 ;
LPITEMIDLIST lpi = 0 ;
HRESULT hr ;
hr=SHGetDesktopFolder( &lpsf) ;
if( SUCCEEDED(hr))
{
TreeView_DeleteAllItems( hwndTreeView) ;
FillTreeView( hwndTreeView, lpsf, NULL, TVI_ROOT) ;
}
if( lpsf)
lpsf -> lpVtbl -> Release( lpsf) ;
}
break ;
case MN_LIST:
{
SwitchView( CTRL( hwnd, IDD_LISTVIEW), LVS_LIST) ;
}
break ;
}
break ;
}
}
return DefWindowProc( hwnd, msg, wParam, lParam) ;
}
BOOL DoTheMenuThing( HWND hwnd,
LPSHELLFOLDER lpsfParent,
LPITEMIDLIST lpi,
LPPOINT lppt)
{
LPCONTEXTMENU lpcm ;
HRESULT hr ;
char szTemp[ 64] ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -