mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
944 lines
24 KiB
944 lines
24 KiB
/****************************************************************************/
|
|
/* */
|
|
/* WFTREE.C - */
|
|
/* */
|
|
/* Windows File System Tree Window Proc Routines */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
#include "winfile.h"
|
|
#include "lfn.h"
|
|
#include "wfcopy.h"
|
|
|
|
#include <commctrl.h>
|
|
|
|
#ifdef PROGMAN
|
|
#include "wficon.h"
|
|
#endif
|
|
|
|
HICON
|
|
GetTreeIcon(HWND hWnd);
|
|
|
|
HICON
|
|
GetTreeIcon(HWND hWnd)
|
|
{
|
|
HWND hwndTree, hwndDir;
|
|
|
|
hwndTree = HasTreeWindow(hWnd);
|
|
hwndDir = HasDirWindow(hWnd);
|
|
|
|
if (hwndTree && hwndDir)
|
|
return hicoTreeDir;
|
|
else if (hwndTree)
|
|
return hicoTree;
|
|
else
|
|
return hicoDir;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
GetTreeWindows( HWND hwnd,
|
|
PHWND phwndTree,
|
|
PHWND phwndDir)
|
|
{
|
|
if (phwndTree) {
|
|
*phwndTree = GetDlgItem(hwnd, IDCW_TREECONTROL);
|
|
}
|
|
if (phwndDir) {
|
|
*phwndDir = GetDlgItem(hwnd, IDCW_DIR);
|
|
}
|
|
}
|
|
|
|
|
|
// returns hwndTree, hwndDir or hwndDrives depending on the focus tracking
|
|
// for the window. if none is found we return NULL
|
|
|
|
HWND
|
|
GetTreeFocus(HWND hwndTree)
|
|
{
|
|
HWND hwnd, hwndLast = NULL;
|
|
|
|
if (bDriveBar && GetFocus() == hwndDriveBar)
|
|
return hwndDriveBar;
|
|
|
|
hwndLast = hwnd = (HWND)GetWindowLong(hwndTree, GWL_LASTFOCUS);
|
|
|
|
while (hwnd && hwnd != hwndTree) {
|
|
hwndLast = hwnd;
|
|
hwnd = GetParent(hwnd);
|
|
}
|
|
|
|
return hwndLast;
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* CompactPath() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
BOOL
|
|
CompactPath(HDC hDC, LPTSTR lpszPath, DWORD dx)
|
|
{
|
|
register INT len;
|
|
SIZE sizeF, sizeT;
|
|
LPTSTR lpEnd; /* end of the unfixed string */
|
|
LPTSTR lpFixed; /* start of text that we always display */
|
|
BOOL bEllipsesIn;
|
|
TCHAR szTemp[MAXPATHLEN];
|
|
DWORD dxEllipses;
|
|
|
|
//
|
|
// Does it already fit?
|
|
//
|
|
GetTextExtentPoint32(hDC, lpszPath, lstrlen(lpszPath), &sizeF);
|
|
if (sizeF.cx <= (INT)dx)
|
|
return(TRUE);
|
|
|
|
//
|
|
// Search backwards for the '\', and man, it better be there!
|
|
//
|
|
lpFixed = lpszPath + lstrlen(lpszPath) - 1;
|
|
while (*lpFixed != CHAR_BACKSLASH)
|
|
lpFixed--;
|
|
|
|
// Save this guy to prevent overlap.
|
|
lstrcpy(szTemp, lpFixed);
|
|
|
|
lpEnd = lpFixed;
|
|
bEllipsesIn = FALSE;
|
|
|
|
GetTextExtentPoint32(hDC, szEllipses, 3, &sizeF);
|
|
dxEllipses = sizeF.cx;
|
|
|
|
GetTextExtentPoint32(hDC, lpFixed, lstrlen(lpFixed), &sizeF);
|
|
|
|
while (TRUE) {
|
|
GetTextExtentPoint32(hDC, lpszPath, lpEnd - lpszPath, &sizeT);
|
|
len = sizeF.cx + sizeT.cx;
|
|
|
|
if (bEllipsesIn)
|
|
len += dxEllipses;
|
|
|
|
if (len <= (INT)dx)
|
|
break;
|
|
|
|
bEllipsesIn = TRUE;
|
|
|
|
if (lpEnd <= lpszPath) {
|
|
|
|
// Things didn't fit.
|
|
|
|
lstrcpy(lpszPath, szEllipses);
|
|
lstrcat(lpszPath, szTemp);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Step back a character.
|
|
--lpEnd;
|
|
}
|
|
|
|
if (bEllipsesIn) {
|
|
lstrcpy(lpEnd, szEllipses);
|
|
lstrcat(lpEnd, szTemp);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: ResizeSplit
|
|
//
|
|
// Synopsis: Creates/resizes kids of MDI child for give path or
|
|
// resizes (perhaps creating/destroying) kids based on dxSplit
|
|
//
|
|
// IN hwnd Window to change
|
|
// IN dxSplit
|
|
//
|
|
//
|
|
// Return: TRUE = success
|
|
// FALSE = fail (out of mem, can't create win, unresizable tree)
|
|
//
|
|
//
|
|
// Assumes:
|
|
//
|
|
// Effects:
|
|
//
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
ResizeSplit(HWND hwnd, INT dxSplit)
|
|
{
|
|
RECT rc;
|
|
HWND hwndTree, hwndDir, hwndLB;
|
|
DWORD dwTemp;
|
|
|
|
GetTreeWindows(hwnd, &hwndTree, &hwndDir);
|
|
|
|
if (hwndTree && GetWindowLong(hwndTree, GWL_READLEVEL))
|
|
return FALSE;
|
|
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
if (dxSplit > dxDriveBitmap * 2) {
|
|
|
|
if (!hwndTree) { // make new tree window
|
|
|
|
hwndTree = CreateWindowEx(0L,
|
|
szTreeControlClass,
|
|
NULL,
|
|
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
|
|
0, 0, 0, 0,
|
|
hwnd,
|
|
(HMENU)IDCW_TREECONTROL,
|
|
hAppInstance, NULL);
|
|
|
|
if (!hwndTree)
|
|
return FALSE;
|
|
|
|
//
|
|
// only reset this if the dir window already
|
|
// exists, that is we are creating the tree
|
|
// by splitting open a dir window
|
|
//
|
|
if (hwndDir)
|
|
SendMessage(hwndTree, TC_SETDRIVE, MAKEWORD(FALSE, 0), 0L);
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// In this conditional, always set dxSplit=0.
|
|
//
|
|
if (hwndTree) { // we are closing the tree window
|
|
|
|
//
|
|
// If the directory window is empty, then set the focus to the
|
|
// drives window.
|
|
//
|
|
if (hwndDir) {
|
|
hwndLB = GetDlgItem (hwndDir,IDCW_LISTBOX);
|
|
if (hwndLB) {
|
|
SendMessage (hwndLB,LB_GETTEXT,0,(LPARAM)(LPTSTR) &dwTemp);
|
|
if (!dwTemp)
|
|
SetFocus(hwndDriveBar);
|
|
}
|
|
}
|
|
DestroyWindow(hwndTree);
|
|
}
|
|
dxSplit = 0;
|
|
}
|
|
|
|
if ((rc.right - dxSplit) > dxDriveBitmap * 2) {
|
|
|
|
if (!hwndDir) {
|
|
hwndDir = CreateWindowEx(0L,
|
|
szDirClass,
|
|
NULL,
|
|
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
|
|
0, 0, 0, 0,
|
|
hwnd,
|
|
(HMENU)IDCW_DIR,
|
|
hAppInstance,
|
|
NULL);
|
|
if (!hwndDir)
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Must invalidate: if viewing extreme left, paint residue left.
|
|
//
|
|
InvalidateRect(hwndDir, NULL, TRUE);
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// Again, always set dxSplit
|
|
//
|
|
if (hwndDir) {
|
|
DestroyWindow(hwndDir);
|
|
}
|
|
dxSplit = rc.right;
|
|
}
|
|
|
|
|
|
SetWindowLong(hwnd, GWL_SPLIT, dxSplit);
|
|
|
|
UpdateStatus(hwnd);
|
|
EnableCheckTBButtons(hwnd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
SwitchDriveSelection(HWND hwndChild, BOOL bSelectToolbarDrive)
|
|
{
|
|
DRIVE drive;
|
|
DRIVEIND i, driveIndOld, driveIndOldFocus;
|
|
RECT rc;
|
|
|
|
drive = GetWindowLong(hwndChild, GWL_TYPE);
|
|
|
|
if (TYPE_SEARCH == drive) {
|
|
|
|
drive = (DRIVE)SendMessage(hwndSearch, FS_GETDRIVE, 0, 0L) - CHAR_A;
|
|
}
|
|
|
|
|
|
driveIndOld = GetWindowLong(hwndDriveBar, GWL_CURDRIVEIND);
|
|
driveIndOldFocus = GetWindowLong(hwndDriveBar, GWL_CURDRIVEFOCUS);
|
|
|
|
for (i=0; i < cDrives; i++) {
|
|
if (rgiDrive[i] == drive) {
|
|
SetWindowLong(hwndDriveBar, GWL_CURDRIVEIND, i);
|
|
SetWindowLong(hwndDriveBar, GWL_CURDRIVEFOCUS, i);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == cDrives)
|
|
return; // didn't find drive; it must have been invalidated
|
|
// other code (such as tree walk) will handle
|
|
|
|
if (bDriveBar) {
|
|
|
|
//
|
|
// Optimization: don't invalidate whole drive bar, just the
|
|
// two drives that change.
|
|
//
|
|
// was: InvalidateRect(hwndDriveBar, NULL, TRUE);
|
|
//
|
|
|
|
GetDriveRect(i, &rc);
|
|
InvalidateRect(hwndDriveBar, &rc, TRUE);
|
|
|
|
GetDriveRect(driveIndOld, &rc);
|
|
InvalidateRect(hwndDriveBar, &rc, TRUE);
|
|
|
|
GetDriveRect(driveIndOldFocus, &rc);
|
|
InvalidateRect(hwndDriveBar, &rc, TRUE);
|
|
|
|
UpdateWindow(hwndDriveBar);
|
|
}
|
|
|
|
// made optional to prevent extra refreshing.
|
|
if (bSelectToolbarDrive)
|
|
SelectToolbarDrive(i);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------*/
|
|
// */
|
|
// TreeWndProc() - */
|
|
// */
|
|
//--------------------------------------------------------------------------*/
|
|
|
|
// WndProc for the MDI child window containing the drives, volume, and
|
|
// directory tree child windows.
|
|
|
|
LONG
|
|
TreeWndProc(
|
|
register HWND hwnd,
|
|
UINT uMsg,
|
|
register WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
HWND hwndTree, hwndDir, hwndFocus;
|
|
TCHAR szDir[2*MAXPATHLEN];
|
|
|
|
RECT rc;
|
|
HDC hdc;
|
|
|
|
switch (uMsg) {
|
|
|
|
case WM_MENUSELECT:
|
|
|
|
if (GET_WM_MENUSELECT_HMENU(wParam, lParam)) {
|
|
|
|
//
|
|
// Save the menu the user selected
|
|
//
|
|
uMenuID = GET_WM_MENUSELECT_CMD(wParam, lParam);
|
|
uMenuFlags = GET_WM_MENUSELECT_FLAGS(wParam, lParam);
|
|
hMenu = GET_WM_MENUSELECT_HMENU(wParam, lParam);
|
|
|
|
bMDIFrameSysMenu = FALSE;
|
|
}
|
|
|
|
MenuHelp((WORD)uMsg, wParam, lParam, GetMenu(hwndFrame),
|
|
hAppInstance, hwndStatus, (LPDWORD)dwMenuIDs);
|
|
break;
|
|
|
|
case WM_FSC:
|
|
|
|
if (hwndDir = HasDirWindow(hwnd))
|
|
SendMessage(hwndDir, uMsg, wParam, lParam);
|
|
|
|
break;
|
|
|
|
case FS_NOTIFYRESUME:
|
|
|
|
if (hwndDir = HasDirWindow(hwnd)) {
|
|
SendMessage(hwnd, FS_GETDIRECTORY, COUNTOF(szDir), (LPARAM)szDir);
|
|
|
|
ModifyWatchList(hwnd, szDir, FILE_NOTIFY_CHANGE_FLAGS);
|
|
}
|
|
break;
|
|
|
|
case FS_CHANGEDRIVES:
|
|
{
|
|
GetMDIWindowText(hwnd, szDir, COUNTOF(szDir));
|
|
SetMDIWindowText(hwnd, szDir); /* refresh label in title */
|
|
RedoDriveWindows((HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L));
|
|
|
|
break;
|
|
}
|
|
|
|
case FS_GETSELECTION:
|
|
{
|
|
#define pfDir (BOOL *)lParam
|
|
LPTSTR p;
|
|
|
|
GetTreeWindows(hwnd, &hwndTree, &hwndDir);
|
|
hwndFocus = GetTreeFocus(hwnd);
|
|
|
|
if (hwndFocus == hwndDir || !hwndTree) {
|
|
return SendMessage(hwndDir, FS_GETSELECTION, wParam, lParam);
|
|
} else {
|
|
|
|
//
|
|
// +2 for checkesc safety
|
|
//
|
|
p = (LPTSTR)LocalAlloc(LPTR, ByteCountOf(MAXPATHLEN + 2));
|
|
if (p) {
|
|
SendMessage(hwnd, FS_GETDIRECTORY, MAXPATHLEN, (DWORD)(LPTSTR)p);
|
|
StripBackslash(p);
|
|
|
|
if (!(wParam & 16)) CheckEsc(p);
|
|
|
|
if (wParam == 2) { // BUG ??? wParam should be fMostRecentOnly
|
|
if (pfDir) {
|
|
*pfDir = IsLFN(p);
|
|
}
|
|
LocalFree((HANDLE)p);
|
|
return (LONG)p;
|
|
}
|
|
}
|
|
if (pfDir) {
|
|
*pfDir = TRUE;
|
|
}
|
|
return (LONG)p;
|
|
}
|
|
#undef pfDir
|
|
}
|
|
|
|
case FS_GETDIRECTORY:
|
|
|
|
// wParam is the length of the string pointed to by lParam
|
|
// returns in lParam ANSI directory string with
|
|
// a trailing backslash. if you want to do a SetCurrentDirecotor()
|
|
// you must first StripBackslash() the thing!
|
|
|
|
GetMDIWindowText(hwnd, (LPTSTR)lParam, (INT)wParam); // get the string
|
|
StripFilespec((LPTSTR)lParam); // Remove the trailing extention
|
|
AddBackslash((LPTSTR)lParam); // terminate with a backslash
|
|
break;
|
|
|
|
|
|
case FS_GETFILESPEC:
|
|
|
|
// WARNING: Requires ((LPTSTR)lparam)[MAXPATHLEN] space!
|
|
// (TreeControlWndProc WM_COMMAND LBN_SELCHANGE broke this!)
|
|
|
|
// returns the current filespec (from View.Include...). this is
|
|
// an uppercase ANSI string
|
|
|
|
GetMDIWindowText(hwnd, (LPTSTR)lParam, (INT)wParam);
|
|
StripPath((LPTSTR)lParam);
|
|
break;
|
|
|
|
// redirect these messages to the drive icons to get the same
|
|
// result as dropping on the active drive.
|
|
// this is especially useful when we are minimized
|
|
|
|
case WM_DRAGSELECT:
|
|
case WM_QUERYDROPOBJECT:
|
|
case WM_DROPOBJECT:
|
|
|
|
// This code is really messed up since there is only one drive bar.
|
|
// Fix the case for Iconic windows but the uniconic state is weird
|
|
|
|
#define lpds ((LPDROPSTRUCT)lParam)
|
|
|
|
if (IsIconic(hwnd) || hwnd != (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L)) {
|
|
if (hwndDir = HasDirWindow(hwnd)) {
|
|
lpds->dwControlData = (DWORD) -1;
|
|
return SendMessage(hwndDir, uMsg, wParam, lParam);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
#undef lpds
|
|
|
|
if (hwndDriveBar) {
|
|
|
|
LONG lRet;
|
|
|
|
hwndDropChild = hwnd;
|
|
lRet = SendMessage(hwndDriveBar, uMsg, wParam, lParam);
|
|
hwndDropChild = NULL;
|
|
return lRet;
|
|
}
|
|
|
|
if (hwndDir = HasDirWindow(hwnd)) {
|
|
return SendMessage(hwndDir, uMsg, wParam, lParam);
|
|
}
|
|
|
|
break;
|
|
|
|
case FS_GETDRIVE:
|
|
|
|
GetTreeWindows(hwnd, &hwndTree, &hwndDir);
|
|
|
|
if (hwndTree)
|
|
return SendMessage(hwndTree, uMsg, wParam, lParam);
|
|
else
|
|
return SendMessage(hwndDir, uMsg, wParam, lParam);
|
|
|
|
break;
|
|
|
|
case WM_CREATE:
|
|
{
|
|
#define lpcs ((LPCREATESTRUCT)lParam)
|
|
#define lpmdics ((LPMDICREATESTRUCT)(lpcs->lpCreateParams))
|
|
|
|
INT dxSplit;
|
|
DRIVE drive;
|
|
WCHAR szPath[2 * MAXFILENAMELEN];
|
|
|
|
//
|
|
// lpcs->lpszName is the path we are opening the
|
|
// window for (has extension stuff "*.*")
|
|
//
|
|
drive = DRIVEID(lpcs->lpszName);
|
|
|
|
SetWindowLong(hwnd, GWL_TYPE, drive);
|
|
|
|
//
|
|
// if dxSplit is negative we split in the middle
|
|
//
|
|
dxSplit = (INT)lpmdics->lParam;
|
|
|
|
//
|
|
// if dxSplit is negative we split in the middle
|
|
//
|
|
if (dxSplit < 0)
|
|
dxSplit = lpcs->cx / 2;
|
|
|
|
SetWindowLong(hwnd, GWL_NOTIFYPAUSE, 0L);
|
|
SetWindowLong(hwnd, GWL_SPLIT, dxSplit);
|
|
SetWindowLong(hwnd, GWL_LASTFOCUS, 0L);
|
|
SetWindowLong(hwnd, GWL_FSCFLAG, FALSE);
|
|
|
|
SetWindowLong(hwnd, GWL_VOLNAME, 0L);
|
|
SetWindowLong(hwnd, GWL_PATHLEN, 0L);
|
|
|
|
#ifdef PROGMAN
|
|
SetWindowLong(hwnd, GWL_PICONBLOCK, 0L);
|
|
#endif
|
|
|
|
if (!ResizeSplit(hwnd, dxSplit))
|
|
return -1;
|
|
|
|
GetTreeWindows(hwnd, &hwndTree, &hwndDir);
|
|
SetWindowLong(hwnd, GWL_LASTFOCUS, (LONG)(hwndTree ? hwndTree : hwndDir));
|
|
|
|
iNumWindows++;
|
|
|
|
GetMDIWindowText(hwnd, szPath, COUNTOF(szPath));
|
|
SetMDIWindowText(hwnd, szPath);
|
|
|
|
break;
|
|
#undef lpcs
|
|
#undef lpmdics
|
|
}
|
|
|
|
case WM_CLOSE:
|
|
|
|
if (hwndTree = HasTreeWindow(hwnd)) {
|
|
|
|
//
|
|
// don't close if we are reading the tree
|
|
//
|
|
if (GetWindowLong(hwndTree, GWL_READLEVEL))
|
|
break;
|
|
}
|
|
|
|
//
|
|
// don't allow the last MDI child to be closed!
|
|
//
|
|
|
|
if (!IsLastWindow()) {
|
|
iNumWindows--;
|
|
|
|
//
|
|
// don't leave current dir on floppies
|
|
//
|
|
GetSystemDirectory(szDir, COUNTOF(szDir));
|
|
SheSetCurDrive(DRIVEID(szDir));
|
|
|
|
goto DEF_MDI_PROC; // this will close this window
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
LPWSTR lpszVolName;
|
|
|
|
//
|
|
// Free GWL_VOLNAME
|
|
//
|
|
lpszVolName = (LPTSTR)GetWindowLong(hwnd, GWL_VOLNAME);
|
|
|
|
if (lpszVolName)
|
|
LocalFree(lpszVolName);
|
|
|
|
break;
|
|
}
|
|
case WM_MDIACTIVATE:
|
|
|
|
//
|
|
// Invalidate the cache since we are switching windows
|
|
//
|
|
ExtSelItemsInvalidate();
|
|
|
|
//
|
|
// we are receiving the activation
|
|
//
|
|
if (GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wParam, lParam)) {
|
|
|
|
#ifdef PROGMAN
|
|
IconMDIActivate();
|
|
#endif
|
|
|
|
EnableCheckTBButtons(hwnd);
|
|
|
|
SPC_SET_INVALID(qFreeSpace);
|
|
|
|
UpdateStatus(hwnd);
|
|
|
|
hwndFocus = (HWND)GetWindowLong(hwnd, GWL_LASTFOCUS);
|
|
SetFocus(hwndFocus);
|
|
|
|
SwitchDriveSelection(hwnd, TRUE);
|
|
}
|
|
else if (hwndDriveBar)
|
|
SendMessage(hwndDriveBar, uMsg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
|
|
hwndFocus = (HWND)GetWindowLong(hwnd, GWL_LASTFOCUS);
|
|
SetFocus(hwndFocus);
|
|
break;
|
|
|
|
case WM_INITMENUPOPUP:
|
|
if (HIWORD(lParam)) {
|
|
EnableMenuItem((HMENU)wParam, SC_CLOSE,
|
|
IsLastWindow() ? MF_BYCOMMAND | MF_DISABLED | MF_GRAYED :
|
|
MF_ENABLED);
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_SYSCOMMAND:
|
|
|
|
if (wParam != SC_SPLIT)
|
|
goto DEF_MDI_PROC;
|
|
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
lParam = MAKELONG(rc.right / 2, 0);
|
|
|
|
// fall through
|
|
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
MSG msg;
|
|
INT x, y, dx, dy;
|
|
|
|
if (IsIconic(hwnd))
|
|
break;
|
|
|
|
y = 0;
|
|
|
|
x = LOWORD(lParam);
|
|
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
dx = 4;
|
|
dy = rc.bottom - y; // the height of the client less the drives window
|
|
|
|
hdc = GetDC(hwnd);
|
|
|
|
// split bar loop
|
|
|
|
PatBlt(hdc, x - dx / 2, y, dx, dy, PATINVERT);
|
|
|
|
SetCapture(hwnd);
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
|
|
|
if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ||
|
|
(msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)) {
|
|
|
|
if (msg.message == WM_LBUTTONUP || msg.message == WM_LBUTTONDOWN)
|
|
break;
|
|
|
|
if (msg.message == WM_KEYDOWN) {
|
|
|
|
if (msg.wParam == VK_LEFT) {
|
|
msg.message = WM_MOUSEMOVE;
|
|
msg.pt.x -= 2;
|
|
} else if (msg.wParam == VK_RIGHT) {
|
|
msg.message = WM_MOUSEMOVE;
|
|
msg.pt.x += 2;
|
|
} else if (msg.wParam == VK_RETURN ||
|
|
msg.wParam == VK_ESCAPE) {
|
|
break;
|
|
}
|
|
|
|
SetCursorPos(msg.pt.x, msg.pt.y);
|
|
}
|
|
|
|
if (msg.message == WM_MOUSEMOVE) {
|
|
|
|
// erase old
|
|
|
|
PatBlt(hdc, x - dx / 2, y, dx, dy, PATINVERT);
|
|
ScreenToClient(hwnd, &msg.pt);
|
|
x = msg.pt.x;
|
|
|
|
// put down new
|
|
|
|
PatBlt(hdc, x - dx / 2, y, dx, dy, PATINVERT);
|
|
}
|
|
} else {
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
ReleaseCapture();
|
|
|
|
// erase old
|
|
|
|
PatBlt(hdc, x - dx / 2, y, dx, dy, PATINVERT);
|
|
ReleaseDC(hwnd, hdc);
|
|
|
|
if (msg.wParam != VK_ESCAPE) {
|
|
|
|
if (ResizeSplit(hwnd, x))
|
|
SendMessage(hwnd, WM_SIZE, SIZENOMDICRAP, MAKELONG(rc.right, rc.bottom));
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case WM_QUERYDRAGICON:
|
|
return (LONG)GetTreeIcon(hwnd);
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
|
|
if (IsIconic(hwnd)) {
|
|
// this paints the background of the icon properly, doing
|
|
// brush allignment and other nasty stuff
|
|
|
|
DefWindowProc(hwnd, WM_ICONERASEBKGND, wParam, 0L);
|
|
} else {
|
|
//
|
|
// Don't bother since we will be redrawing everything
|
|
// over it anyway.
|
|
//
|
|
}
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HBRUSH hbr;
|
|
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
|
|
if (IsIconic(hwnd)) {
|
|
DrawIcon(hdc, 0, 0, GetTreeIcon(hwnd));
|
|
} else {
|
|
GetClientRect(hwnd, &rc);
|
|
rc.left = GetSplit(hwnd);
|
|
|
|
if (rc.left >= rc.right)
|
|
rc.left = 0;
|
|
|
|
rc.right = rc.left + dxFrame;
|
|
|
|
// draw the black pane handle
|
|
|
|
rc.top = rc.bottom - GetSystemMetrics(SM_CYHSCROLL);
|
|
FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
|
|
|
|
if (hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW))) {
|
|
|
|
rc.bottom = rc.top;
|
|
rc.top = 0;
|
|
|
|
FillRect(hdc, &rc, hbr);
|
|
|
|
DeleteObject(hbr);
|
|
}
|
|
}
|
|
EndPaint(hwnd, &ps);
|
|
break;
|
|
}
|
|
|
|
|
|
case WM_SIZE:
|
|
|
|
if (wParam != SIZEICONIC) {
|
|
|
|
//
|
|
// Must invalidate rect to clear up the hwndDir display
|
|
// when the view is single column (partial/full details)
|
|
// and it's scrolled to the extreme left. (Either resizing
|
|
// larger or maximizing)
|
|
//
|
|
// To avoid nasty double flicker, we turn off the redraw
|
|
// flag for the list box (hwndDir is set to IDCW_LISTBOX).
|
|
// Then we redraw then repaint.
|
|
//
|
|
if (hwndDir = HasDirWindow(hwnd)) {
|
|
|
|
hwndDir = GetDlgItem(hwndDir, IDCW_LISTBOX);
|
|
SendMessage(hwndDir, WM_SETREDRAW, FALSE, 0L);
|
|
}
|
|
|
|
ResizeWindows(hwnd,LOWORD(lParam),HIWORD(lParam));
|
|
|
|
//
|
|
// When hwndDir is non-NULL, it holds the IDCW_LISTBOX set
|
|
// above. Now set redraw true and repaint.
|
|
//
|
|
if (hwndDir) {
|
|
|
|
SendMessage(hwndDir, WM_SETREDRAW, TRUE, 0L);
|
|
|
|
InvalidateRect(hwndDir, NULL, TRUE);
|
|
UpdateWindow(hwndDir);
|
|
}
|
|
|
|
} else if (IsLastWindow()) {
|
|
|
|
//
|
|
// A bug in MDI sometimes causes us to get the input focus
|
|
// even though we're minimized. Prevent that...
|
|
//
|
|
SetFocus(GetParent(hwnd));
|
|
}
|
|
|
|
//
|
|
// if wParam is SIZENOMDICRAP this WM_SIZE was generated by us.
|
|
// don't let this through to the DefMDIChildProc().
|
|
// that might change the min/max state, (show parameter)
|
|
//
|
|
|
|
if (wParam == SIZENOMDICRAP)
|
|
break;
|
|
|
|
//
|
|
// FALL THRU
|
|
//
|
|
|
|
default:
|
|
|
|
DEF_MDI_PROC:
|
|
|
|
return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
|
|
VOID
|
|
ResizeWindows(HWND hwndParent,INT dxWindow, INT dyWindow)
|
|
{
|
|
INT y, dy, split;
|
|
|
|
HWND hwndTree, hwndDir;
|
|
RECT rc;
|
|
|
|
GetTreeWindows(hwndParent, &hwndTree, &hwndDir);
|
|
|
|
y = -dyBorder;
|
|
|
|
split = GetSplit(hwndParent);
|
|
|
|
//
|
|
// user has been fixed to do this right
|
|
//
|
|
dy = dyWindow - y + dyBorder;
|
|
|
|
if (hwndTree) {
|
|
if (!hwndDir)
|
|
MoveWindow(hwndTree, dxFrame, y, dxWindow - dxFrame + dyBorder, dy, TRUE);
|
|
else
|
|
MoveWindow(hwndTree, -dyBorder, y, split + dyBorder, dy, TRUE);
|
|
}
|
|
|
|
if (hwndDir) {
|
|
if (!hwndTree)
|
|
MoveWindow(hwndDir, dxFrame, y, dxWindow - dxFrame + dyBorder, dy, TRUE);
|
|
else
|
|
MoveWindow(hwndDir, split + dxFrame, y,
|
|
dxWindow - split - dxFrame + dyBorder, dy, TRUE);
|
|
}
|
|
|
|
//
|
|
// since this window is not CS_HREDRAW | CS_VREDRAW we need to force
|
|
// the repaint of the split
|
|
//
|
|
rc.top = y;
|
|
rc.bottom = y + dy;
|
|
|
|
//
|
|
// yutakas
|
|
// When split moved, Tree Window couldn't redraw.
|
|
//
|
|
if ((hwndTree) && (!(rc.left = GetScrollPos(GetDlgItem(hwndTree,
|
|
IDCW_TREELISTBOX),
|
|
SB_HORZ) ?
|
|
0 :
|
|
split))) {
|
|
|
|
rc.right = split;
|
|
InvalidateRect(hwndParent, &rc, FALSE);
|
|
}
|
|
|
|
rc.left = split;
|
|
rc.right = split + dxFrame;
|
|
|
|
InvalidateRect(hwndParent, &rc, TRUE);
|
|
UpdateWindow(hwndParent);
|
|
}
|
|
|
|
|