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.
1579 lines
41 KiB
1579 lines
41 KiB
/****************************************************************************/
|
|
/* */
|
|
/* WFINIT.C - */
|
|
/* */
|
|
/* Windows File System Initialization Routines */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
#include "stdlib.h"
|
|
|
|
#include "winfile.h"
|
|
#include "lfn.h"
|
|
#include "wnetcaps.h" // WNetGetCaps()
|
|
|
|
#ifdef PROGMAN
|
|
#include "wficon.h"
|
|
#endif
|
|
|
|
|
|
typedef VOID (APIENTRY *FNPENAPP)(WORD, BOOL);
|
|
|
|
VOID (APIENTRY *lpfnRegisterPenApp)(WORD, BOOL);
|
|
|
|
BYTE chPenReg[] = "RegisterPenApp"; // used in GetProcAddress call
|
|
|
|
TCHAR szNTlanman[] = TEXT("ntlanman.dll");
|
|
TCHAR szHelv[] = TEXT("MS Shell Dlg");
|
|
/*
|
|
** 6/13/95 FloydR Note re: MS Gothic, MS Shell Dlg and System fonts for Japan.
|
|
** For 3.51J, the "MS Shell Dlg" font is linked to the "MS Gothic" Japanese
|
|
** TTF. This means that all this stuff about using different fonts for
|
|
** Japan (and Korea/China) is gone.
|
|
*/
|
|
|
|
HBITMAP hbmSave;
|
|
|
|
DWORD RGBToBGR(DWORD rgb);
|
|
VOID BoilThatDustSpec(register WCHAR *pStart, BOOL bLoadIt);
|
|
VOID DoRunEquals(PINT pnCmdShow);
|
|
VOID GetSavedWindow(LPWSTR szBuf, PWINDOW pwin);
|
|
VOID GetSettings(VOID);
|
|
|
|
#define MENU_STRING_SIZ 80
|
|
#define PROFILE_STRING_SIZ 300
|
|
|
|
|
|
INT
|
|
GetHeightFromPointsString(LPTSTR szPoints)
|
|
{
|
|
HDC hdc;
|
|
INT height;
|
|
|
|
hdc = GetDC(NULL);
|
|
height = MulDiv(-atoi(szPoints), GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
return height;
|
|
}
|
|
|
|
|
|
VOID
|
|
BiasMenu(HMENU hMenu, UINT Bias)
|
|
{
|
|
UINT pos, id, count;
|
|
HMENU hSubMenu;
|
|
TCHAR szMenuString[MENU_STRING_SIZ];
|
|
|
|
count = GetMenuItemCount(hMenu);
|
|
|
|
if (count == (UINT) -1)
|
|
return;
|
|
|
|
for (pos = 0; pos < count; pos++) {
|
|
|
|
id = GetMenuItemID(hMenu, pos);
|
|
|
|
if (id == (UINT) -1) {
|
|
// must be a popup, recurse and update all ID's here
|
|
if (hSubMenu = GetSubMenu(hMenu, pos))
|
|
BiasMenu(hSubMenu, Bias);
|
|
} else if (id) {
|
|
// replace the item that was there with a new
|
|
// one with the id adjusted
|
|
|
|
GetMenuString(hMenu, pos, szMenuString, COUNTOF(szMenuString), MF_BYPOSITION);
|
|
DeleteMenu(hMenu, pos, MF_BYPOSITION);
|
|
InsertMenu(hMenu, pos, MF_BYPOSITION | MF_STRING, id + Bias, szMenuString);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InitExtensions()
|
|
{
|
|
TCHAR szBuf[PROFILE_STRING_SIZ];
|
|
TCHAR szPath[MAXPATHLEN];
|
|
LPTSTR p;
|
|
HANDLE hMod;
|
|
FM_EXT_PROC fp;
|
|
HMENU hMenu;
|
|
INT iMax;
|
|
HMENU hMenuFrame;
|
|
HWND hwndActive;
|
|
INT iMenuOffset=0;
|
|
BOOL bUnicode;
|
|
|
|
hMenuFrame = GetMenu(hwndFrame);
|
|
|
|
hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L);
|
|
if (hwndActive && GetWindowLong(hwndActive, GWL_STYLE) & WS_MAXIMIZE)
|
|
iMax = 1;
|
|
else
|
|
iMax = 0;
|
|
|
|
GetPrivateProfileString(szAddons, NULL, szNULL, szBuf, COUNTOF(szBuf), szTheINIFile);
|
|
|
|
for (p = szBuf; *p && iNumExtensions < MAX_EXTENSIONS; p += lstrlen(p) + 1) {
|
|
|
|
GetPrivateProfileString(szAddons, p, szNULL, szPath, COUNTOF(szPath), szTheINIFile);
|
|
|
|
hMod = LoadLibrary(szPath);
|
|
|
|
if (hMod) {
|
|
fp = (FM_EXT_PROC)GetProcAddress(hMod, FM_EXT_PROC_ENTRYW);
|
|
if (fp) {
|
|
bUnicode = TRUE;
|
|
} else {
|
|
fp = (FM_EXT_PROC)GetProcAddress(hMod, FM_EXT_PROC_ENTRYA);
|
|
bUnicode = FALSE;
|
|
}
|
|
|
|
if (fp) {
|
|
UINT bias;
|
|
FMS_LOADA lsA;
|
|
FMS_LOADW lsW;
|
|
|
|
bias = ((IDM_EXTENSIONS + iNumExtensions + 1)*100);
|
|
|
|
// We are now going to bias each menu, since extensions
|
|
// don't know about each other and may clash IDM_xx if
|
|
// we don't.
|
|
|
|
// Our system is as follow: IDMs 1000 - 6999 are reserved
|
|
// for us (menus 0 - 5 inclusive). Thus, IDMs
|
|
// 7000 - 1199 is reserved for extensions.
|
|
// This is why we added 1 in the above line to compute
|
|
// bias: IDMs 0000-0999 are not used for menu 0.
|
|
|
|
if (bUnicode)
|
|
lsW.wMenuDelta = bias;
|
|
else
|
|
lsA.wMenuDelta = bias;
|
|
|
|
if ((*fp)(hwndFrame, FMEVENT_LOAD, bUnicode ? (LONG)&lsW : (LONG)&lsA)) {
|
|
|
|
if ((bUnicode ? lsW.dwSize : lsA.dwSize)
|
|
!= (bUnicode ? sizeof(FMS_LOADW) : sizeof(FMS_LOADA)))
|
|
goto LoadFail;
|
|
|
|
hMenu = bUnicode ? lsW.hMenu : lsA.hMenu;
|
|
|
|
extensions[iNumExtensions].ExtProc = fp;
|
|
extensions[iNumExtensions].Delta = bias;
|
|
extensions[iNumExtensions].hModule = hMod;
|
|
extensions[iNumExtensions].hMenu = hMenu;
|
|
extensions[iNumExtensions].bUnicode = bUnicode;
|
|
|
|
if (hMenu) {
|
|
BiasMenu(hMenu, bias);
|
|
|
|
if (bUnicode) {
|
|
InsertMenuW(hMenuFrame,
|
|
IDM_EXTENSIONS + iMenuOffset + iMax,
|
|
MF_BYPOSITION | MF_POPUP,
|
|
(UINT) hMenu, lsW.szMenuName);
|
|
} else {
|
|
InsertMenuA(hMenuFrame,
|
|
IDM_EXTENSIONS + iMenuOffset + iMax,
|
|
MF_BYPOSITION | MF_POPUP,
|
|
(UINT) hMenu, lsA.szMenuName);
|
|
}
|
|
iMenuOffset++;
|
|
}
|
|
|
|
iNumExtensions++;
|
|
|
|
} else {
|
|
goto LoadFail;
|
|
}
|
|
} else {
|
|
LoadFail:
|
|
FreeLibrary(hMod);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* GetSettings() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
VOID
|
|
GetSettings()
|
|
{
|
|
TCHAR szTemp[128];
|
|
INT size;
|
|
INT weight;
|
|
|
|
INT bfCharset;
|
|
|
|
/* Get the flags out of the INI file. */
|
|
bMinOnRun = GetPrivateProfileInt(szSettings, szMinOnRun, bMinOnRun, szTheINIFile);
|
|
wTextAttribs = (WORD)GetPrivateProfileInt(szSettings, szLowerCase, wTextAttribs, szTheINIFile);
|
|
bStatusBar = GetPrivateProfileInt(szSettings, szStatusBar, bStatusBar, szTheINIFile);
|
|
|
|
bDriveBar = GetPrivateProfileInt(szSettings, szDriveBar, bDriveBar, szTheINIFile);
|
|
bToolbar = GetPrivateProfileInt(szSettings, szToolbar, bToolbar, szTheINIFile);
|
|
|
|
bNewWinOnConnect = GetPrivateProfileInt(szSettings, szNewWinOnNetConnect, bNewWinOnConnect, szTheINIFile);
|
|
bConfirmDelete = GetPrivateProfileInt(szSettings, szConfirmDelete, bConfirmDelete, szTheINIFile);
|
|
bConfirmSubDel = GetPrivateProfileInt(szSettings, szConfirmSubDel, bConfirmSubDel, szTheINIFile);
|
|
bConfirmReplace = GetPrivateProfileInt(szSettings, szConfirmReplace,bConfirmReplace,szTheINIFile);
|
|
bConfirmMouse = GetPrivateProfileInt(szSettings, szConfirmMouse, bConfirmMouse, szTheINIFile);
|
|
bConfirmFormat = GetPrivateProfileInt(szSettings, szConfirmFormat, bConfirmFormat, szTheINIFile);
|
|
bConfirmReadOnly= GetPrivateProfileInt(szSettings, szConfirmReadOnly, bConfirmReadOnly, szTheINIFile);
|
|
uChangeNotifyTime= GetPrivateProfileInt(szSettings, szChangeNotifyTime, uChangeNotifyTime, szTheINIFile);
|
|
bSaveSettings = GetPrivateProfileInt(szSettings, szSaveSettings, bSaveSettings, szTheINIFile);
|
|
weight = GetPrivateProfileInt(szSettings, szFaceWeight, 400, szTheINIFile);
|
|
|
|
GetPrivateProfileString(szSettings,
|
|
szSize,
|
|
bJAPAN ?
|
|
TEXT("14") :
|
|
TEXT("8"),
|
|
szTemp,
|
|
COUNTOF(szTemp),
|
|
szTheINIFile);
|
|
|
|
size = GetHeightFromPointsString(szTemp);
|
|
|
|
GetPrivateProfileString(szSettings,
|
|
szFace,
|
|
szHelv,
|
|
szTemp,
|
|
COUNTOF(szTemp),
|
|
szTheINIFile);
|
|
|
|
|
|
bfCharset = bJAPAN ?
|
|
GetPrivateProfileInt(szSettings,
|
|
szSaveCharset,
|
|
SHIFTJIS_CHARSET,
|
|
szTheINIFile) :
|
|
ANSI_CHARSET;
|
|
|
|
hFont = CreateFont(size,
|
|
0, 0, 0, weight,
|
|
wTextAttribs & TA_ITALIC, 0, 0,
|
|
bfCharset,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY,
|
|
DEFAULT_PITCH | FF_SWISS,
|
|
szTemp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* GetInternational() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
VOID
|
|
GetInternational()
|
|
{
|
|
GetLocaleInfoW(lcid, LOCALE_STHOUSAND, (LPWSTR) szComma, COUNTOF(szComma));
|
|
GetLocaleInfoW(lcid, LOCALE_SDECIMAL, (LPWSTR) szDecimal, COUNTOF(szDecimal));
|
|
}
|
|
|
|
|
|
INT
|
|
GetDriveOffset(register DRIVE drive)
|
|
{
|
|
if (IsRemoteDrive(drive)) {
|
|
|
|
if (aDriveInfo[drive].bRemembered)
|
|
return dxDriveBitmap * 5;
|
|
else
|
|
return dxDriveBitmap * 4;
|
|
}
|
|
|
|
|
|
if (IsRemovableDrive(drive))
|
|
return dxDriveBitmap * 1;
|
|
|
|
if (IsRamDrive(drive))
|
|
return dxDriveBitmap * 3;
|
|
|
|
if (IsCDRomDrive(drive))
|
|
return dxDriveBitmap * 0;
|
|
|
|
return dxDriveBitmap * 2;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* InitMenus() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
VOID
|
|
InitMenus()
|
|
{
|
|
HMENU hMenu;
|
|
INT iMax;
|
|
TCHAR szValue[MAXPATHLEN];
|
|
HWND hwndActive;
|
|
HMENU hMenuOptions;
|
|
|
|
TCHAR szPathName[MAXPATHLEN];
|
|
|
|
hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L);
|
|
if (hwndActive && GetWindowLong(hwndActive, GWL_STYLE) & WS_MAXIMIZE)
|
|
iMax = 1;
|
|
else
|
|
iMax = 0;
|
|
|
|
GetPrivateProfileString(szSettings, szUndelete, szNULL, szValue, COUNTOF(szValue), szTheINIFile);
|
|
|
|
if (szValue[0]) {
|
|
|
|
// create explicit filename to avoid searching the path
|
|
|
|
GetSystemDirectory(szPathName, COUNTOF(szPathName));
|
|
AddBackslash(szPathName);
|
|
lstrcat(szPathName, szValue);
|
|
|
|
hModUndelete = LoadLibrary(szValue);
|
|
|
|
if (hModUndelete) {
|
|
lpfpUndelete = (FM_UNDELETE_PROC)GetProcAddress(hModUndelete, UNDELETE_ENTRYW);
|
|
|
|
if (lpfpUndelete) {
|
|
bUndeleteUnicode = TRUE;
|
|
} else {
|
|
lpfpUndelete = (FM_UNDELETE_PROC)GetProcAddress(hModUndelete, UNDELETE_ENTRYA);
|
|
bUndeleteUnicode = FALSE;
|
|
}
|
|
|
|
if (lpfpUndelete) {
|
|
hMenu = GetSubMenu(GetMenu(hwndFrame), IDM_FILE + iMax);
|
|
LoadString(hAppInstance, IDS_UNDELETE, szValue, COUNTOF(szValue));
|
|
InsertMenu(hMenu, 4, MF_BYPOSITION | MF_STRING, IDM_UNDELETE, szValue);
|
|
}
|
|
} else {
|
|
FreeLibrary(hModUndelete);
|
|
hModUndelete = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// use submenu because we are doing this by position
|
|
//
|
|
hMenu = GetSubMenu(GetMenu(hwndFrame), IDM_DISK + iMax);
|
|
|
|
if (WNetStat(NS_CONNECTDLG)) { // Network Connections...
|
|
|
|
InsertMenu(hMenu, 4, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
|
|
|
LoadString(hAppInstance, IDS_NEWWINONCONNECT, szValue, COUNTOF(szValue));
|
|
hMenuOptions = GetSubMenu(GetMenu(hwndFrame), 4);
|
|
InsertMenu(hMenuOptions, 8, MF_BYPOSITION | MF_STRING, IDM_NEWWINONCONNECT, szValue);
|
|
|
|
LoadString(hAppInstance, IDS_CONNECT, szValue, COUNTOF(szValue));
|
|
InsertMenu(hMenu, 5, MF_BYPOSITION | MF_STRING, IDM_CONNECT, szValue);
|
|
|
|
LoadString(hAppInstance, IDS_DISCONNECT, szValue, COUNTOF(szValue));
|
|
InsertMenu(hMenu, 6, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT, szValue);
|
|
|
|
}
|
|
|
|
// Shared Directories
|
|
if (WNetStat(NS_SHAREDLG)) {
|
|
|
|
InsertMenu(hMenu, 7, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
|
|
|
LoadString(hAppInstance, IDS_SHAREAS, szValue, COUNTOF(szValue));
|
|
InsertMenu(hMenu, 8, MF_BYPOSITION | MF_STRING, IDM_SHAREAS, szValue);
|
|
|
|
LoadString(hAppInstance, IDS_STOPSHARE, szValue, COUNTOF(szValue));
|
|
InsertMenu(hMenu, 9, MF_BYPOSITION | MF_STRING, IDM_STOPSHARE, szValue);
|
|
|
|
}
|
|
|
|
//
|
|
// Init the Disk menu.
|
|
//
|
|
hMenu = GetMenu(hwndFrame);
|
|
|
|
if (nFloppies == 0) {
|
|
EnableMenuItem(hMenu, IDM_DISKCOPY, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hMenu, IDM_FORMAT, MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
|
|
|
|
if (bStatusBar)
|
|
CheckMenuItem(hMenu, IDM_STATUSBAR, MF_BYCOMMAND | MF_CHECKED);
|
|
if (bMinOnRun)
|
|
CheckMenuItem(hMenu, IDM_MINONRUN, MF_BYCOMMAND | MF_CHECKED);
|
|
if (bSaveSettings)
|
|
CheckMenuItem(hMenu, IDM_SAVESETTINGS, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (bDriveBar)
|
|
CheckMenuItem(hMenu, IDM_DRIVEBAR, MF_BYCOMMAND | MF_CHECKED);
|
|
if (bToolbar)
|
|
CheckMenuItem(hMenu, IDM_TOOLBAR, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (bNewWinOnConnect)
|
|
CheckMenuItem(hMenu, IDM_NEWWINONCONNECT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
|
|
//
|
|
// Init menus after the window/menu has been created
|
|
//
|
|
InitExtensions();
|
|
|
|
InitToolbarButtons();
|
|
|
|
//
|
|
// Redraw the menu bar since it's already displayed
|
|
//
|
|
DrawMenuBar(hwndFrame);
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* BoilThatDustSpec() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* Parses the command line (if any) passed into WINFILE and exec's any tokens
|
|
* it may contain.
|
|
*/
|
|
|
|
VOID
|
|
BoilThatDustSpec(register TCHAR *pStart, BOOL bLoadIt)
|
|
{
|
|
register TCHAR *pEnd;
|
|
DWORD ret;
|
|
BOOL bFinished;
|
|
|
|
if (*pStart == CHAR_NULL)
|
|
return;
|
|
|
|
bFinished = FALSE;
|
|
while (!bFinished) {
|
|
pEnd = pStart;
|
|
while ((*pEnd) && (*pEnd != CHAR_SPACE) && (*pEnd != CHAR_COMMA))
|
|
++pEnd;
|
|
|
|
if (*pEnd == CHAR_NULL)
|
|
bFinished = TRUE;
|
|
else
|
|
*pEnd = CHAR_NULL;
|
|
|
|
ret = ExecProgram(pStart, szNULL, NULL, bLoadIt);
|
|
if (ret)
|
|
MyMessageBox(NULL, IDS_EXECERRTITLE, ret, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
|
|
pStart = pEnd+1;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// BOOL LoadBitmaps()
|
|
//
|
|
// this routine loads DIB bitmaps, and "fixes up" their color tables
|
|
// so that we get the desired result for the device we are on.
|
|
//
|
|
// this routine requires:
|
|
// the DIB is a 16 color DIB authored with the standard windows colors
|
|
// bright green (FF 00 00) is converted to the background color!
|
|
// light grey (C0 C0 C0) is replaced with the button face color
|
|
// dark grey (80 80 80) is replaced with the button shadow color
|
|
//
|
|
// this means you can't have any of these colors in your bitmap
|
|
//
|
|
|
|
#define BACKGROUND 0x0000FF00 // bright green
|
|
#define BACKGROUNDSEL 0x00FF00FF // bright red
|
|
#define BUTTONFACE 0x00C0C0C0 // bright grey
|
|
#define BUTTONSHADOW 0x00808080 // dark grey
|
|
|
|
DWORD
|
|
FlipColor(DWORD rgb)
|
|
{
|
|
return RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb));
|
|
}
|
|
|
|
|
|
BOOL
|
|
LoadBitmaps(VOID)
|
|
{
|
|
HDC hdc;
|
|
HANDLE h;
|
|
DWORD FAR *p;
|
|
LPBYTE lpBits;
|
|
HANDLE hRes;
|
|
LPBITMAPINFOHEADER lpBitmapInfo;
|
|
INT numcolors;
|
|
DWORD rgbSelected;
|
|
DWORD rgbUnselected;
|
|
UINT cbBitmapSize;
|
|
LPBITMAPINFOHEADER lpBitmapData;
|
|
|
|
rgbSelected = FlipColor(GetSysColor(COLOR_HIGHLIGHT));
|
|
rgbUnselected = FlipColor(GetSysColor(COLOR_WINDOW));
|
|
|
|
h = FindResource(hAppInstance, (LPTSTR) MAKEINTRESOURCE(BITMAPS), RT_BITMAP);
|
|
hRes = LoadResource(hAppInstance, h);
|
|
|
|
// Lock the bitmap data and make a copy of it for the mask and the bitmap.
|
|
//
|
|
cbBitmapSize = SizeofResource( hAppInstance, h );
|
|
lpBitmapData = (LPBITMAPINFOHEADER)( hRes );
|
|
|
|
lpBitmapInfo = (LPBITMAPINFOHEADER) LocalAlloc(LMEM_FIXED, cbBitmapSize);
|
|
|
|
if (!lpBitmapInfo) {
|
|
return FALSE;
|
|
}
|
|
|
|
CopyMemory( (PBYTE)lpBitmapInfo, (PBYTE)lpBitmapData, cbBitmapSize );
|
|
|
|
//
|
|
// Get a pointer into the color table of the bitmaps, cache the number of
|
|
// bits per pixel
|
|
//
|
|
p = (DWORD FAR *)((PBYTE)(lpBitmapInfo) + lpBitmapInfo->biSize);
|
|
|
|
//
|
|
// Search for the Solid Blue entry and replace it with the current
|
|
// background RGB.
|
|
//
|
|
numcolors = 16;
|
|
|
|
while (numcolors-- > 0) {
|
|
if (*p == BACKGROUND)
|
|
*p = rgbUnselected;
|
|
else if (*p == BACKGROUNDSEL)
|
|
*p = rgbSelected;
|
|
else if (*p == BUTTONFACE)
|
|
*p = FlipColor(GetSysColor(COLOR_BTNFACE));
|
|
else if (*p == BUTTONSHADOW)
|
|
*p = FlipColor(GetSysColor(COLOR_BTNSHADOW));
|
|
|
|
p++;
|
|
}
|
|
|
|
//
|
|
// Now create the DIB.
|
|
//
|
|
|
|
//
|
|
// First skip over the header structure
|
|
//
|
|
lpBits = (LPBYTE)(lpBitmapInfo + 1);
|
|
|
|
//
|
|
// Skip the color table entries, if any
|
|
//
|
|
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
|
|
|
|
//
|
|
// Create a color bitmap compatible with the display device
|
|
//
|
|
hdc = GetDC(NULL);
|
|
if (hdcMem = CreateCompatibleDC(hdc)) {
|
|
|
|
if (hbmBitmaps = CreateDIBitmap(hdc, lpBitmapInfo, (DWORD)CBM_INIT, lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS))
|
|
hbmSave = SelectObject(hdcMem, hbmBitmaps);
|
|
|
|
}
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
#ifndef KKBUGFIX
|
|
//It is not necessary to free a resource loaded by using the LoadResource function.
|
|
LocalUnlock(hRes);
|
|
FreeResource(hRes);
|
|
#endif
|
|
|
|
LocalFree(lpBitmapInfo);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: GetSavedWindow
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// IN szBuf buffer to parse out all save win info (NULL = default)
|
|
// OUT pwin pwin filled with szBuf fields.
|
|
//
|
|
// Return:
|
|
//
|
|
//
|
|
// Assumes:
|
|
//
|
|
// Effects:
|
|
//
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
VOID
|
|
GetSavedWindow(
|
|
LPWSTR szBuf,
|
|
PWINDOW pwin)
|
|
{
|
|
PINT pint;
|
|
INT count;
|
|
|
|
//
|
|
// defaults
|
|
//
|
|
// (CW_USEDEFAULT must be type casted since it is defined
|
|
// as an int.
|
|
//
|
|
pwin->rc.right = pwin->rc.left = (LONG)CW_USEDEFAULT;
|
|
pwin->pt.x = pwin->pt.y = pwin->rc.top = pwin->rc.bottom = 0;
|
|
pwin->sw = SW_SHOWNORMAL;
|
|
pwin->uSort = IDD_NAME;
|
|
pwin->uView = VIEW_NAMEONLY;
|
|
pwin->dwAttribs = ATTR_DEFAULT;
|
|
pwin->nSplit = 0;
|
|
|
|
pwin->szDir[0] = CHAR_NULL;
|
|
|
|
if (!szBuf)
|
|
return;
|
|
|
|
//
|
|
// BUGBUG: (LATER)
|
|
// This assumes the members of the point structure are
|
|
// the same size as INT (sizeof(LONG) == sizeof(INT) == sizeof(UINT))!
|
|
//
|
|
|
|
count = 0;
|
|
pint = (PINT)&pwin->rc; // start by filling the rect
|
|
|
|
while (*szBuf && count < 11) {
|
|
|
|
*pint++ = atoi(szBuf); // advance to next field
|
|
|
|
while (*szBuf && *szBuf != CHAR_COMMA)
|
|
szBuf++;
|
|
|
|
while (*szBuf && *szBuf == CHAR_COMMA)
|
|
szBuf++;
|
|
|
|
count++;
|
|
}
|
|
|
|
lstrcpy(pwin->szDir, szBuf); // this is the directory
|
|
}
|
|
|
|
|
|
BOOL
|
|
CheckDirExists(
|
|
LPWSTR szDir)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if (IsNetDrive(DRIVEID(szDir)) == 2) {
|
|
|
|
CheckDrive(hwndFrame, DRIVEID(szDir), FUNC_SETDRIVE);
|
|
return TRUE;
|
|
}
|
|
|
|
if (IsValidDisk(DRIVEID(szDir)))
|
|
bRet = !SheChangeDir(szDir);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CreateSavedWindows()
|
|
{
|
|
WCHAR buf[2*MAXPATHLEN+7*7], key[10];
|
|
WINDOW win;
|
|
|
|
//
|
|
// since win.szDir is bigger.
|
|
//
|
|
WCHAR szDir[2*MAXPATHLEN];
|
|
|
|
INT nDirNum;
|
|
HWND hwnd;
|
|
INT iNumTrees;
|
|
|
|
//
|
|
// make sure this thing exists so we don't hit drives that don't
|
|
// exist any more
|
|
//
|
|
nDirNum = 1;
|
|
iNumTrees = 0;
|
|
|
|
do {
|
|
wsprintf(key, szDirKeyFormat, nDirNum++);
|
|
|
|
GetPrivateProfileString(szSettings, key, szNULL, buf, COUNTOF(buf), szTheINIFile);
|
|
|
|
if (*buf) {
|
|
|
|
GetSavedWindow(buf, &win);
|
|
|
|
//
|
|
// clean off some junk so we
|
|
// can do this test
|
|
//
|
|
lstrcpy(szDir, win.szDir);
|
|
StripFilespec(szDir);
|
|
StripBackslash(szDir);
|
|
|
|
if (!CheckDirExists(szDir))
|
|
continue;
|
|
|
|
uNewView = win.uView;
|
|
uNewSort = win.uSort;
|
|
dwNewAttribs = win.dwAttribs;
|
|
|
|
hwnd = CreateTreeWindow(win.szDir,
|
|
win.rc.left,
|
|
win.rc.top,
|
|
win.rc.right - win.rc.left,
|
|
win.rc.bottom - win.rc.top,
|
|
win.nSplit);
|
|
|
|
if (!hwnd) {
|
|
continue;
|
|
}
|
|
|
|
iNumTrees++;
|
|
|
|
//
|
|
// keep track of this for now...
|
|
//
|
|
SetInternalWindowPos(hwnd, win.sw, &win.rc, &win.pt);
|
|
}
|
|
|
|
} while (*buf);
|
|
|
|
//
|
|
// if nothing was saved create a tree for the current drive
|
|
//
|
|
if (!iNumTrees) {
|
|
|
|
lstrcpy(buf, szOriginalDirPath);
|
|
AddBackslash(buf);
|
|
lstrcat(buf, szStarDotStar);
|
|
|
|
//
|
|
// default to split window
|
|
//
|
|
hwnd = CreateTreeWindow(buf, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, -1);
|
|
|
|
if (!hwnd)
|
|
return FALSE;
|
|
|
|
iNumTrees++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// void GetTextStuff(HDC hdc)
|
|
//
|
|
// this computes all the globals that are dependant on the
|
|
// currently selected font
|
|
//
|
|
// in:
|
|
// hdc DC with font selected into it
|
|
//
|
|
|
|
VOID
|
|
GetTextStuff(HDC hdc)
|
|
{
|
|
SIZE size;
|
|
TEXTMETRIC tm;
|
|
|
|
GetTextExtentPoint32(hdc, TEXT("W"), 1, &size);
|
|
|
|
dxText = size.cx;
|
|
dyText = size.cy;
|
|
|
|
//
|
|
// the old method of GetTextExtent("M") was not good enough for the
|
|
// drive bar because in Arial 8 (the default font), a lowercase 'w'
|
|
// is actually wider than an uppercase 'M', which causes drive W in
|
|
// the drive bar to clip. rather than play around with a couple of
|
|
// sample letters and taking the max, or fudging the width, we just
|
|
// get the metrics and use the real max character width.
|
|
//
|
|
// to avoid the tree window indents looking too wide, we use the old
|
|
// 'M' extent everywhere besides the drive bar, though.
|
|
//
|
|
GetTextMetrics(hdc, &tm);
|
|
|
|
//
|
|
// these are all dependant on the text metrics
|
|
//
|
|
dxDrive = dxDriveBitmap + tm.tmMaxCharWidth + (4*dyBorderx2);
|
|
dyDrive = max(dyDriveBitmap + (4*dyBorderx2), dyText);
|
|
dyFileName = max(dyText, dyFolder); // + dyBorder;
|
|
}
|
|
|
|
UINT
|
|
FillDocType(
|
|
PPDOCBUCKET ppDoc,
|
|
LPCWSTR pszSection,
|
|
LPCWSTR pszDefault,
|
|
DWORD dwParm)
|
|
{
|
|
LPWSTR pszDocuments = NULL;
|
|
LPWSTR p;
|
|
LPWSTR p2;
|
|
UINT uLen = 0;
|
|
|
|
UINT uRetval = 0;
|
|
|
|
do {
|
|
|
|
uLen += 32;
|
|
|
|
if (pszDocuments)
|
|
LocalFree((HLOCAL)pszDocuments);
|
|
|
|
pszDocuments = LocalAlloc(LMEM_FIXED, uLen*sizeof(WCHAR));
|
|
|
|
if (!pszDocuments) {
|
|
return 0;
|
|
}
|
|
|
|
} while (GetProfileString(szWindows,
|
|
pszSection,
|
|
pszDefault,
|
|
pszDocuments,
|
|
uLen) == (DWORD)uLen-2);
|
|
|
|
//
|
|
// Parse through string, searching for blanks
|
|
//
|
|
for (p=pszDocuments; *p; p++) {
|
|
|
|
if (CHAR_SPACE == *p) {
|
|
*p = CHAR_NULL;
|
|
}
|
|
}
|
|
|
|
for(p2=pszDocuments; p2<p; p2++) {
|
|
|
|
if (*p2) {
|
|
if (DocInsert(ppDoc, p2, dwParm) == 1)
|
|
uRetval++;
|
|
|
|
while(*p2 && p2!=p)
|
|
p2++;
|
|
}
|
|
}
|
|
|
|
LocalFree((HLOCAL)pszDocuments);
|
|
|
|
return uRetval;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* InitFileManager() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
BOOL
|
|
InitFileManager(
|
|
HANDLE hInstance,
|
|
LPWSTR lpCmdLine,
|
|
INT nCmdShow)
|
|
{
|
|
INT i;
|
|
HDC hdcScreen;
|
|
|
|
//
|
|
// 2*MAXPATHLEN since may have huge filter.
|
|
//
|
|
WCHAR szBuffer[2*MAXPATHLEN];
|
|
|
|
HCURSOR hcurArrow;
|
|
WNDCLASS wndClass;
|
|
WINDOW win;
|
|
HWND hwnd;
|
|
HANDLE hOld;
|
|
RECT rcT, rcS;
|
|
WCHAR szTemp[80];
|
|
DWORD Ignore;
|
|
|
|
HANDLE hThread;
|
|
DWORD dwRetval;
|
|
|
|
hThread = GetCurrentThread();
|
|
|
|
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
InitializeCriticalSection(&CriticalSectionPath);
|
|
|
|
// ProfStart();
|
|
|
|
//
|
|
// Preserve this instance's module handle
|
|
//
|
|
hAppInstance = hInstance;
|
|
|
|
lcid = GetThreadLocale();
|
|
|
|
|
|
JAPANBEGIN
|
|
bJapan = (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_JAPANESE);
|
|
JAPANEND
|
|
|
|
if (*lpCmdLine)
|
|
nCmdShow = SW_SHOWMINNOACTIVE;
|
|
|
|
//
|
|
// Constructors for info system.
|
|
// Must always do since these never fail and we don't test for
|
|
// non-initialization during destruction (if FindWindow returns valid)
|
|
//
|
|
M_Info();
|
|
|
|
M_Type();
|
|
M_Space();
|
|
M_NetCon();
|
|
M_VolInfo();
|
|
|
|
//
|
|
// Bounce errors to us, not fs.
|
|
//
|
|
SetErrorMode(1);
|
|
|
|
for (i=0; i<26;i++) {
|
|
I_Space(i);
|
|
}
|
|
|
|
if (lpfnRegisterPenApp = (FNPENAPP)GetProcAddress((HANDLE)GetSystemMetrics(SM_PENWINDOWS), chPenReg))
|
|
(*lpfnRegisterPenApp)(1, TRUE);
|
|
|
|
|
|
//
|
|
// Remember the current directory.
|
|
//
|
|
SheGetDir(0L, szOriginalDirPath);
|
|
|
|
if (*lpCmdLine) {
|
|
|
|
if (dwRetval = ExecProgram(lpCmdLine, pszNextComponent(lpCmdLine), NULL, FALSE))
|
|
MyMessageBox(NULL, IDS_EXECERRTITLE, dwRetval, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
else
|
|
nCmdShow = SW_SHOWMINNOACTIVE;
|
|
}
|
|
|
|
//
|
|
// Read WINFILE.INI and set the approriate variables.
|
|
//
|
|
GetSettings();
|
|
|
|
dyBorder = GetSystemMetrics(SM_CYBORDER);
|
|
dyBorderx2 = dyBorder * 2;
|
|
dxFrame = GetSystemMetrics(SM_CXFRAME) - dyBorder;
|
|
|
|
dxDriveBitmap = DRIVES_WIDTH;
|
|
dyDriveBitmap = DRIVES_HEIGHT;
|
|
dxFolder = FILES_WIDTH;
|
|
dyFolder = FILES_HEIGHT;
|
|
|
|
if (!LoadBitmaps())
|
|
return FALSE;
|
|
|
|
hicoTree = LoadIcon(hAppInstance, (LPTSTR) MAKEINTRESOURCE(TREEICON));
|
|
hicoTreeDir = LoadIcon(hAppInstance, (LPTSTR) MAKEINTRESOURCE(TREEDIRICON));
|
|
hicoDir = LoadIcon(hAppInstance, (LPTSTR) MAKEINTRESOURCE(DIRICON));
|
|
|
|
chFirstDrive = CHAR_a;
|
|
|
|
// now build the parameters based on the font we will be using
|
|
|
|
hdcScreen = GetDC(NULL);
|
|
|
|
hOld = SelectObject(hdcScreen, hFont);
|
|
GetTextStuff(hdcScreen);
|
|
if (hOld)
|
|
SelectObject(hdcScreen, hOld);
|
|
|
|
dxClickRect = max(GetSystemMetrics(SM_CXDOUBLECLK) / 2, 2 * dxText);
|
|
dyClickRect = max(GetSystemMetrics(SM_CYDOUBLECLK) / 2, dyText);
|
|
|
|
|
|
GetPrivateProfileString(szSettings,
|
|
szDriveListFace,
|
|
szHelv,
|
|
szTemp,
|
|
COUNTOF(szTemp),
|
|
szTheINIFile);
|
|
|
|
hfontDriveList = CreateFont(GetHeightFromPointsString(TEXT("8")),
|
|
0, 0,
|
|
0, 400, 0,
|
|
0,
|
|
0,
|
|
bJAPAN ?
|
|
SHIFTJIS_CHARSET :
|
|
ANSI_CHARSET,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY,
|
|
VARIABLE_PITCH | FF_SWISS,
|
|
szTemp);
|
|
|
|
// use the smaller font for Status bar so that messages fix in it.
|
|
if( bJAPAN) {
|
|
hFontStatus = CreateFont(GetHeightFromPointsString(TEXT("10")),
|
|
0, 0,
|
|
0, 400, 0,
|
|
0,
|
|
0,
|
|
SHIFTJIS_CHARSET,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY,
|
|
VARIABLE_PITCH,
|
|
szHelv );
|
|
}
|
|
ReleaseDC(NULL, hdcScreen);
|
|
|
|
/* Load the accelerator table. */
|
|
hAccel = LoadAccelerators(hInstance, (LPTSTR) MAKEINTRESOURCE(WFACCELTABLE));
|
|
|
|
wHelpMessage = RegisterWindowMessage(TEXT("ShellHelp"));
|
|
wBrowseMessage = RegisterWindowMessage(TEXT("commdlg_help"));
|
|
|
|
hhkMsgFilter = SetWindowsHook(WH_MSGFILTER, (HOOKPROC)MessageFilter);
|
|
|
|
hcurArrow = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
wndClass.lpszClassName = szFrameClass;
|
|
wndClass.style = 0L;
|
|
wndClass.lpfnWndProc = FrameWndProc;
|
|
wndClass.cbClsExtra = 0;
|
|
wndClass.cbWndExtra = 0;
|
|
wndClass.hInstance = hInstance;
|
|
wndClass.hIcon = LoadIcon(hInstance, (LPTSTR) MAKEINTRESOURCE(APPICON));
|
|
wndClass.hCursor = hcurArrow;
|
|
wndClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); // COLOR_WINDOW+1;
|
|
wndClass.lpszMenuName = (LPTSTR) MAKEINTRESOURCE(FRAMEMENU);
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
wndClass.lpszClassName = szTreeClass;
|
|
|
|
wndClass.style = 0; //WS_CLIPCHILDREN; //CS_VREDRAW | CS_HREDRAW;
|
|
|
|
wndClass.lpfnWndProc = TreeWndProc;
|
|
// wndClass.cbClsExtra = 0;
|
|
|
|
#ifdef PROGMAN
|
|
wndClass.cbWndExtra = 11 * sizeof(LONG);
|
|
#else
|
|
wndClass.cbWndExtra = 10 * sizeof(LONG);
|
|
#endif
|
|
|
|
|
|
// wndClass.hInstance = hInstance;
|
|
wndClass.hIcon = NULL;
|
|
wndClass.hCursor = LoadCursor(hInstance, (LPTSTR) MAKEINTRESOURCE(SPLITCURSOR));
|
|
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|
wndClass.lpszMenuName = NULL;
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
wndClass.lpszClassName = szDrivesClass;
|
|
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
wndClass.lpfnWndProc = DrivesWndProc;
|
|
// wndClass.cbClsExtra = 0;
|
|
wndClass.cbWndExtra = sizeof(LONG) +// GWL_CURDRIVEIND
|
|
sizeof(LONG) +// GWL_CURDRIVEFOCUS
|
|
sizeof(LONG); // GWL_LPSTRVOLUME
|
|
|
|
// wndClass.hInstance = hInstance;
|
|
// wndClass.hIcon = NULL;
|
|
wndClass.hCursor = hcurArrow;
|
|
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
|
|
// wndClass.lpszMenuName = NULL;
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
wndClass.lpszClassName = szTreeControlClass;
|
|
wndClass.style = CS_DBLCLKS;
|
|
wndClass.lpfnWndProc = TreeControlWndProc;
|
|
// wndClass.cbClsExtra = 0;
|
|
wndClass.cbWndExtra = 2 * sizeof(LONG); // GWL_READLEVEL
|
|
// wndClass.hInstance = hInstance;
|
|
// wndClass.hIcon = NULL;
|
|
wndClass.hCursor = hcurArrow;
|
|
wndClass.hbrBackground = NULL;
|
|
// wndClass.lpszMenuName = NULL;
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
wndClass.lpszClassName = szDirClass;
|
|
wndClass.style = 0; //CS_VREDRAW | CS_HREDRAW;
|
|
wndClass.lpfnWndProc = DirWndProc;
|
|
// wndClass.cbClsExtra = 0;
|
|
wndClass.cbWndExtra = 7 * sizeof(LONG);
|
|
// wndClass.hInstance = hInstance;
|
|
wndClass.hIcon = NULL;
|
|
// wndClass.hCursor = hcurArrow;
|
|
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|
// wndClass.lpszMenuName = NULL;
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
wndClass.lpszClassName = szSearchClass;
|
|
wndClass.style = 0L;
|
|
wndClass.lpfnWndProc = SearchWndProc;
|
|
// wndClass.cbClsExtra = 0;
|
|
wndClass.cbWndExtra = 10 * sizeof(LONG);
|
|
|
|
// wndClass.hInstance = hInstance;
|
|
wndClass.hIcon = LoadIcon(hInstance, (LPTSTR) MAKEINTRESOURCE(DIRICON));
|
|
// wndClass.hCursor = NULL;
|
|
wndClass.hbrBackground = NULL;
|
|
// wndClass.lpszMenuName = NULL;
|
|
|
|
if (!RegisterClass(&wndClass)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!LoadString(hInstance, IDS_WINFILE, szTitle, COUNTOF(szTitle))) {
|
|
return FALSE;
|
|
}
|
|
|
|
GetPrivateProfileString(szSettings, szWindow, szNULL, szBuffer, COUNTOF(szBuffer), szTheINIFile);
|
|
GetSavedWindow(szBuffer, &win);
|
|
|
|
// Check that at least some portion of the window is visible;
|
|
// set to screen size if not
|
|
|
|
rcT.left = rcT.top = 0;
|
|
rcT.right = GetSystemMetrics(SM_CXSCREEN);
|
|
rcT.bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
// right and bottom are width and height, so convert to coordinates
|
|
|
|
win.rc.right += win.rc.left;
|
|
win.rc.bottom += win.rc.top;
|
|
|
|
if (!IntersectRect(&rcS, &rcT, &win.rc))
|
|
{
|
|
rcT.right = rcT.bottom = (LONG)CW_USEDEFAULT;
|
|
win.rc = rcT;
|
|
}
|
|
|
|
// Now convert back again
|
|
|
|
win.rc.right -= win.rc.left;
|
|
win.rc.bottom -= win.rc.top;
|
|
|
|
|
|
//
|
|
// Check to see if another copy of winfile is running. If
|
|
// so, either bring it to the foreground, or restore it to
|
|
// a window (from an icon).
|
|
//
|
|
{
|
|
HWND hwndPrev;
|
|
HWND hwnd;
|
|
|
|
hwndPrev = FindWindow (szFrameClass, NULL);
|
|
|
|
if (hwndPrev != NULL) {
|
|
// For Win32, this will accomplish almost the same effect as the
|
|
// above code does for Win 3.0/3.1 [stevecat]
|
|
|
|
hwnd = GetLastActivePopup(hwndPrev);
|
|
|
|
if (IsIconic(hwndPrev)) {
|
|
ShowWindow (hwndPrev, SW_RESTORE);
|
|
SetForegroundWindow (hwndPrev);
|
|
} else {
|
|
SetForegroundWindow (hwnd);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (!CreateWindowEx(0L, szFrameClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
win.rc.left, win.rc.top, win.rc.right, win.rc.bottom,
|
|
NULL, NULL, hInstance, NULL)) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// Now, we need to start the Change Notify thread, so that any changes
|
|
// that happen will be notified. This thread will create handles for
|
|
// each viewed directory and wait on them. If any of the handles are
|
|
// awakened, then the appropriate directory will be sent a message to
|
|
// refresh itself. Another thread will also be created to watch for
|
|
// network connections/disconnections. This will be done via the
|
|
// registry. !! LATER !!
|
|
|
|
InitializeWatchList();
|
|
|
|
bUpdateRun = TRUE;
|
|
//
|
|
// Now create our worker thread and two events to communicate by
|
|
//
|
|
hEventUpdate = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
hEventUpdatePartial = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
hEventNetLoad = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
hEventAcledit = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
hThreadUpdate = CreateThread( NULL,
|
|
0L,
|
|
(LPTHREAD_START_ROUTINE)UpdateInit,
|
|
NULL,
|
|
0L,
|
|
&Ignore);
|
|
|
|
if (!hEventUpdate ||
|
|
!hEventUpdatePartial ||
|
|
!hThreadUpdate ||
|
|
!hEventNetLoad ||
|
|
!hEventAcledit) {
|
|
|
|
LoadFailMessage();
|
|
|
|
bUpdateRun = FALSE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
SetThreadPriority(hThreadUpdate, THREAD_PRIORITY_BELOW_NORMAL);
|
|
|
|
//
|
|
// Reset simple drive info, and don't let anyone block
|
|
//
|
|
ResetDriveInfo();
|
|
SetEvent(hEventUpdatePartial);
|
|
|
|
nFloppies = 0;
|
|
for (i=0; i < cDrives; i++) {
|
|
if (IsRemovableDrive(rgiDrive[i])) {
|
|
|
|
//
|
|
// Avoid Phantom B: problems.
|
|
//
|
|
if ((nFloppies == 1) && (i > 1))
|
|
nFloppies = 2;
|
|
|
|
nFloppies++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Turn off redraw for hwndDriveList since we will display it later
|
|
// (avoid flicker)
|
|
//
|
|
SendMessage(hwndDriveList,WM_SETREDRAW,0,0l);
|
|
|
|
//
|
|
// support forced min or max
|
|
//
|
|
if (nCmdShow == SW_SHOW || nCmdShow == SW_SHOWNORMAL &&
|
|
win.sw != SW_SHOWMINIMIZED)
|
|
|
|
nCmdShow = win.sw;
|
|
|
|
ShowWindow(hwndFrame, nCmdShow);
|
|
|
|
if (bDriveBar) {
|
|
//
|
|
// Update the drive bar
|
|
//
|
|
InvalidateRect(hwndDriveBar, NULL, TRUE);
|
|
}
|
|
UpdateWindow(hwndFrame);
|
|
|
|
//
|
|
// Party time...
|
|
// Slow stuff here
|
|
//
|
|
|
|
LoadString(hInstance, IDS_DIRSREAD, szDirsRead, COUNTOF(szDirsRead));
|
|
LoadString(hInstance, IDS_BYTES, szBytes, COUNTOF(szBytes));
|
|
LoadString(hInstance, IDS_SBYTES, szSBytes, COUNTOF(szSBytes));
|
|
|
|
//
|
|
// Read the International constants out of WIN.INI.
|
|
//
|
|
GetInternational();
|
|
|
|
if (ppProgBucket = DocConstruct()) {
|
|
|
|
FillDocType(ppProgBucket, L"Programs", szDefPrograms, 0);
|
|
}
|
|
|
|
#ifdef PROGMAN
|
|
//
|
|
// Parse Exes that have icons
|
|
//
|
|
|
|
if (ppProgIconBucket = DocConstruct()) {
|
|
|
|
FillDocType(ppProgIconBucket, L"ProgramsIcons", szDefProgramsIcons, 0);
|
|
}
|
|
|
|
if (IconInit()) {
|
|
|
|
// !! LATER !!
|
|
//
|
|
// Eror message
|
|
}
|
|
#endif
|
|
|
|
BuildDocumentStringWorker();
|
|
|
|
if (!InitDirRead()) {
|
|
|
|
LoadFailMessage();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Now draw drive list box
|
|
//
|
|
FillToolbarDrives(0);
|
|
SendMessage(hwndDriveList,WM_SETREDRAW,(WPARAM)TRUE,0l);
|
|
InvalidateRect(hwndDriveList, NULL, TRUE);
|
|
|
|
|
|
//
|
|
// Init Menus fast stuff
|
|
//
|
|
// Init the Disk menu
|
|
//
|
|
InitMenus();
|
|
|
|
|
|
if (!CreateSavedWindows()) {
|
|
return FALSE;
|
|
}
|
|
|
|
ShowWindow(hwndMDIClient, SW_NORMAL);
|
|
|
|
//
|
|
// Kick start the background net read
|
|
//
|
|
// Note: We must avoid deadlock situations by kick starting the network
|
|
// here. There is a possible deadlock if you attempt a WAITNET() before
|
|
// hEventUpdate is first set. This can occur in the wfYield() step
|
|
// of the background read below.
|
|
//
|
|
SetEvent(hEventUpdate);
|
|
|
|
// now refresh all tree windows (start background tree read)
|
|
//
|
|
// since the tree reads happen in the background the user can
|
|
// change the Z order by activating windows once the read
|
|
// starts. to avoid missing a window we must restart the
|
|
// search through the MDI child list, checking to see if the
|
|
// tree has been read yet (if there are any items in the
|
|
// list box). if it has not been read yet we start the read
|
|
|
|
hwnd = GetWindow(hwndMDIClient, GW_CHILD);
|
|
|
|
while (hwnd) {
|
|
HWND hwndTree;
|
|
|
|
if ((hwndTree = HasTreeWindow(hwnd)) &&
|
|
(INT)SendMessage(GetDlgItem(hwndTree, IDCW_TREELISTBOX), LB_GETCOUNT, 0, 0L) == 0) {
|
|
|
|
SendMessage(hwndTree, TC_SETDRIVE, MAKEWORD(FALSE, 0), 0L);
|
|
hwnd = GetWindow(hwndMDIClient, GW_CHILD);
|
|
} else {
|
|
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
|
|
}
|
|
}
|
|
|
|
// ProfStop();
|
|
|
|
// drive refresh taken out of update drive list, must be manually
|
|
// placed here for screen init. Do last.
|
|
// Commented out (unnecessary)
|
|
// FillToolbarDrives(GetSelectedDrive());
|
|
|
|
SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
DeleteBitmaps()
|
|
{
|
|
if (hdcMem) {
|
|
|
|
SelectObject(hdcMem, hbmSave);
|
|
|
|
if (hbmBitmaps)
|
|
DeleteObject(hbmBitmaps);
|
|
DeleteDC(hdcMem);
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// FreeFileManager() -
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
FreeFileManager()
|
|
{
|
|
if (hThreadUpdate && bUpdateRun) {
|
|
UpdateWaitQuit();
|
|
CloseHandle(hThreadUpdate);
|
|
}
|
|
|
|
DeleteCriticalSection(&CriticalSectionPath);
|
|
|
|
#define CLOSEHANDLE(handle) if (handle) CloseHandle(handle)
|
|
|
|
CLOSEHANDLE(hEventNetLoad);
|
|
CLOSEHANDLE(hEventAcledit);
|
|
CLOSEHANDLE(hEventUpdate);
|
|
CLOSEHANDLE(hEventUpdatePartial);
|
|
|
|
DestroyWatchList();
|
|
DestroyDirRead();
|
|
|
|
D_Info();
|
|
|
|
D_Type();
|
|
D_Space();
|
|
D_NetCon();
|
|
D_VolInfo();
|
|
|
|
#ifdef PROGMAN
|
|
IconFree();
|
|
#endif
|
|
|
|
|
|
DocDestruct(ppDocBucket);
|
|
DocDestruct(ppProgBucket);
|
|
#ifdef PROGMAN
|
|
DocDestruct(ppProgIconBucket);
|
|
#endif
|
|
|
|
if (lpfnRegisterPenApp)
|
|
(*lpfnRegisterPenApp)(1, FALSE);
|
|
|
|
DeleteBitmaps();
|
|
|
|
if (hFont)
|
|
DeleteObject(hFont);
|
|
|
|
if (hfontDriveList)
|
|
DeleteObject(hfontDriveList);
|
|
|
|
// use the smaller font for Status bar so that messages fix in it.
|
|
if( bJAPAN ) {
|
|
if (hFontStatus)
|
|
DeleteObject(hFontStatus);
|
|
}
|
|
|
|
//
|
|
// Free the fmifs junk
|
|
//
|
|
if (hfmifsDll)
|
|
FreeLibrary(hfmifsDll);
|
|
|
|
if (hNTLanman)
|
|
FreeLibrary(hNTLanman);
|
|
|
|
if (hMPR)
|
|
FreeLibrary(hMPR);
|
|
|
|
if (hVersion)
|
|
FreeLibrary(hVersion);
|
|
|
|
|
|
#undef CLOSEHANDLE
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: LoadFailMessage
|
|
//
|
|
// Synopsis: Puts up message on load failure.
|
|
//
|
|
// IN VOID
|
|
//
|
|
// Return: VOID
|
|
//
|
|
//
|
|
// Assumes:
|
|
//
|
|
// Effects:
|
|
//
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
LoadFailMessage(VOID)
|
|
{
|
|
WCHAR szMessage[MAXMESSAGELEN];
|
|
|
|
szMessage[0]=0;
|
|
|
|
LoadString(hAppInstance,
|
|
IDS_INITUPDATEFAIL,
|
|
szMessage,
|
|
COUNTOF(szMessage));
|
|
|
|
FormatError(FALSE, szMessage, COUNTOF(szMessage), GetLastError());
|
|
|
|
LoadString(hAppInstance,
|
|
IDS_INITUPDATEFAILTITLE,
|
|
szTitle,
|
|
COUNTOF(szTitle));
|
|
|
|
MessageBox(hwndFrame, szMessage, szTitle, MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|