/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1996 - 1998 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
// DRVPROC.C
#include "cfiler.h"
extern HANDLE ghModule;
extern HANDLEghwndMain;
extern HFONT ghFont;
extern HANDLE ghDrvThread;
extern HANDLE ghMenu;
extern HWND ghwndDrives;
extern HWND ghwndDrv;
extern HWND ghFocusWnd;
extern LPDINFO glpDrives;
extern CRITICAL_SECTION gDrvCS;
/**********************************************************************\
* DrawItem()
*
* in parmeters
* lpdis - Information the owner window must have to determine how
* to paint the owner-draw listbox
*
* Calls DrawText to output a string with the right color in the
* rectangle contained in lpdis
\**********************************************************************/
VOID APIENTRY DrawItem(LPDRAWITEMSTRUCT lpdis) {
COLORREF crOldColor;
TCHARszFile[256];
INT i, nLen;
TCHAR szBuf[275];
TEXTMETRIC tm;
RECT rc;
if (!lpdis) {
ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
return;
}
GetTextMetrics(lpdis->hDC, &tm);
// Filenames such as Q&A.DOC should look correct.
ReplaceEscapeCharacters((LPTSTR)lpdis->itemData, szBuf);
nLen = lstrlen(szBuf);
if (nLen > HEADER_SIZE) {
ErrorMsg(TEXT("fnKey has been Destroyed!"));
crOldColor = SetTextColor(lpdis->hDC, RGB(140, 140, 140));
CopyRect(&rc, &lpdis->rcItem);
rc.left += 1;
lstrcpy(szFile, TEXT("RecoverMe"));
DrawText(lpdis->hDC, szFile, lstrlen(szFile), (LPRECT)&rc, DT_LEFT);
SetTextColor(lpdis->hDC, crOldColor);
return;
}
if (szBuf[0] == TEXT('|')) {
// This is an encrypted file. Select gray as the color.
crOldColor = SetTextColor(lpdis->hDC, RGB(140, 140, 140));
for (i = 0; i < nLen - 1; i++)
szFile[i] = szBuf[i + 1];
szFile[i] = TEXT('\0');
}
else if (szBuf[0] == TEXT('>')) {
// This is an encrypted and signed file.
crOldColor = SetTextColor(lpdis->hDC, RGB(255, 140, 140));
for (i = 0; i < nLen - 1; i++)
szFile[i] = szBuf[i + 1];
szFile[i] = TEXT('\0');
}
else if (szBuf[0] == TEXT(';')) {
// This is a signed only file.
crOldColor = SetTextColor(lpdis->hDC, RGB(255, 0, 0));
for (i = 0; i < nLen - 1; i++)
szFile[i] = szBuf[i + 1];
szFile[i] = TEXT('\0');
}
else
lstrcpy(szFile, szBuf);
CopyRect(&rc, &lpdis->rcItem);
rc.left += 1;
DrawText(lpdis->hDC, szFile, lstrlen(szFile), (LPRECT)&rc, DT_LEFT);
if (szBuf[0] == TEXT('|') || szBuf[0] == TEXT('>') || szBuf[0] == TEXT(';'))
SetTextColor(lpdis->hDC, crOldColor);
return;
}
/**********************************************************************\
* HandleSelectionState()
*
* in parmeters
* lpdis - Information the owner window must have to determine how
* to paint the owner-draw listbox
*
* purpose:
* Handles a change in an item selection state. This function must
* check the current background color for the rectangle contained
* in the DRAWITEMSTRUCT pointer, lpdis. The background color and
* text color must be changed appropriately.
\**********************************************************************/
VOID APIENTRY HandleSelectionState(LPDRAWITEMSTRUCT lpdis)
{
if (!lpdis) {
ErrorMsg(TEXT("HandleSelectionState: lpdis is NULL."));
return;
}
if (lpdis->itemState & ODS_SELECTED) {
if (GetBkColor(lpdis->hDC) == GetSysColor(COLOR_HIGHLIGHT)) {
return;
}
else {
SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
DrawItem(lpdis);
return;
}
}
else {
if (GetBkColor(lpdis->hDC) != GetSysColor(COLOR_WINDOW)) {
return;
}
else {
SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
DrawItem(lpdis);
return;
}
}
}
/**********************************************************************\
* DrawEntireItem()
*
* in parmeters
* lpdis - Information the owner window must have to determine how
* to paint the owner-draw listbox
*
* Sets the background color and the text color and calls DrawItem()
\**********************************************************************/
VOID APIENTRY DrawEntireItem(LPDRAWITEMSTRUCT lpdis)
{
if (!lpdis) {
ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
return;
}
SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
DrawItem(lpdis);
__try {
if (!lpdis) {
ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
return;
}
if (!lpdis->itemData) {
ErrorMsg(TEXT("DrawEntireItem: lpdis->itemData is NULL."));
return;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
ErrorMsg(TEXT("DrawEntireItem: lpdis is BOGUS."));
return;
}
/* Draw or erase appropriate frames */
__try {
HandleSelectionState(lpdis);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
ErrorMsg(TEXT("DrawEntireItem: Attempt to call HandleSelectionState raised an exception."));
return;
}
}
LRESULT WINAPI DrvWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
LPDRAWITEMSTRUCT lpdis;
LPMEASUREITEMSTRUCT lpmis;
LPCOMPAREITEMSTRUCT lpcis;
DWORD dwDirStyle = WS_BORDER | WS_CHILD | WS_VISIBLE |
LBS_NOINTEGRALHEIGHT | LBS_NOTIFY |
LBS_HASSTRINGS | LBS_WANTKEYBOARDINPUT |
LBS_DISABLENOSCROLL | WS_HSCROLL |
WS_VSCROLL |LBS_USETABSTOPS;
DWORD dwFileStyle = WS_BORDER | WS_CHILD | WS_VISIBLE |
LBS_NOINTEGRALHEIGHT | LBS_NOTIFY |
LBS_OWNERDRAWFIXED | LBS_WANTKEYBOARDINPUT |
LBS_DISABLENOSCROLL | WS_HSCROLL |
LBS_EXTENDEDSEL | LBS_MULTIPLESEL |
LBS_MULTICOLUMN | LBS_SORT;
switch (message){
//
// Creates the text and listbox windows for this Drv child and
// saves its handle in the per Drv child DRVCHILDINFO data structure.
//
case WM_CREATE: {
LPCINFO lpCInfo;
DWORD dwLoop;
LPDINFO lpWalk;
LONG lTabs = LISTBOX_TAB_SIZE;
//
// Initialize DRVCHILDINFO structure
//
lpCInfo = (LPCINFO) ((LPCREATESTRUCT) lParam)->lpCreateParams;
if (!lpCInfo) {
ErrorMsg(TEXT("DrvWndProc: lpCInfo is NULL."));
return 0;
}
lpCInfo->hwnd = hwnd;
// Create text window
lpCInfo->hTextWnd = CreateWindow(TEXT("TextClass"), NULL,
SS_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER,
0, 0, 0, 0,
lpCInfo->hwnd,
(HMENU) TEXT_WINDOW_ID,
ghModule,
NULL);
if (!lpCInfo->hTextWnd) {
ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
return 0;
}
// Create Directory and File List boxes
lpCInfo->hDirLB = CreateWindow(TEXT("LISTBOX"), NULL,
dwDirStyle,
0, 0, 0, 0,
lpCInfo->hwnd,
(HMENU) LISTDIR_ID,
ghModule,
NULL);
if (!lpCInfo->hDirLB) {
ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
return 0;
}
// Create directory listbox string table.
lpCInfo->DirTable = TableNew();
if (!lpCInfo->DirTable) {
ErrorMsg(TEXT("WM_CREATE: TableNew failed."));
return 0;
}
lpCInfo->hFileLB = CreateWindow(TEXT("LISTBOX"), NULL,
dwFileStyle,
0, 0, 0, 0,
lpCInfo->hwnd,
(HMENU) LISTFILE_ID,
ghModule,
NULL);
if (!lpCInfo->hFileLB) {
ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
return 0;
}
lpCInfo->FileTable = TableNew();
if (!lpCInfo->FileTable) {
ErrorMsg(TEXT("WM_CREATE: TableNew failed."));
return 0;
}
if (!Logon(hwnd)) {
MessageBox(hwnd, TEXT("DrvWndProc: WM_CREATE: Logon failed. Terminating application."), NULL, MB_OK);
exit(1);
return 0;
}
//
// fDirLeft indicates whether the Directory ListBox defaults to
// the left side of each of the two drive windows.
// fDirExpand indicates whether the Directory Listbox defaults
// to full expansion.
//
lpCInfo->fDirLeft = TRUE;
lpCInfo->fDirExpand = FALSE;
lpCInfo->fSuicide = FALSE;
//
// Create Mutex associated with each list box
//
lpCInfo->hDirMutex = CreateMutex(NULL, FALSE, NULL);
lpCInfo->hFileMutex = CreateMutex(NULL, FALSE, NULL);
//
// Associate window with the current directory LPDINFO structure
// from the Drives linked list
//
dwLoop = GetCurrentDirectory( DIRECTORY_STRING_SIZE,
lpCInfo->CaptionBarText);
CharUpper(lpCInfo->CaptionBarText);
WaitForSingleObject(ghDrvThread, INFINITE);
EnterCriticalSection(&gDrvCS);
lpWalk = glpDrives;
if(dwLoop && dwLoop <= DIRECTORY_STRING_SIZE) {
while(lpWalk && tolower(lpWalk->DriveName[0])
!= tolower((lpCInfo->CaptionBarText)[0]))
lpWalk = lpWalk->next;
if( !lpWalk ){
ErrorMsg(TEXT("Drive Child Create: Drive list failure."));
LeaveCriticalSection(&gDrvCS);
return(-1);
}
}
else{
ErrorMsg(TEXT("Drive Child Create: GetCurrentDir failure."));
LeaveCriticalSection(&gDrvCS);
return(-1);
}
LeaveCriticalSection(&gDrvCS);
lpCInfo->lpDriveInfo = lpWalk;
//
// Save the handle to DRVCHILDINFO in our window structure
//
SetWindowLong(hwnd, GWL_USERDATA, (LONG) lpCInfo);
//
// Initialize child windows
//
if( !SendMessage(lpCInfo->hDirLB, LB_SETTABSTOPS, (WPARAM)1,
(LPARAM)&lTabs) )
ErrorMsg(TEXT("Drv window Create: Set tab stop failure."));
//
// Set default font.
//
SendMessage(lpCInfo->hDirLB, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
SendMessage(lpCInfo->hFileLB, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_REFRESH, (LPARAM)NULL);
return 1;
}
case WM_COMMAND: {
static LPCINFO lpCInfo;
static SELECTINFO Select;
//
// Retrieving this child window's DRVCHILDINFO data for displaying
// messages in the text window
//
lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
if (!lpCInfo) {
ErrorMsg(TEXT("DrvWndProc: WM_COMMAND: lpCInfo is NULL."));
return FALSE;
}
switch (LOWORD(wParam)){
//
// Clears the selection in the active window.
// Sent when user hits escape key.
//
case MM_ESCAPE:{
//
// If there is a directory expand in process, kill the
// thread, and leave the listbox in a semi-expanded state.
// Else, clear file selection, and switch to command window.
//
if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
== WAIT_TIMEOUT ){
lpCInfo->fSuicide = TRUE;
lpCInfo->fEscape = TRUE;
}
else
ReleaseMutex( lpCInfo->hDirMutex );
SendMessage(lpCInfo->hFileLB, LB_SETCURSEL, (WPARAM)-1,
(LPARAM)0);
return 1;
}
case MM_ENCRYPT_DECRYPT: {
if( ghFocusWnd == lpCInfo->hFileLB ) {
RunListBoxItem(lpCInfo, ENCRYPT_DECRYPT);
}
else
if( ghFocusWnd == lpCInfo->hDirLB ){
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
(LPARAM)0) ){
ErrorMsg(TEXT("MM_ENCRYPT_DECRYPT: Filldir failure."));
return 0;
}
}
return 1;
}
case MM_SIGN: {
if( ghFocusWnd == lpCInfo->hFileLB ) {
RunListBoxItem(lpCInfo, SIGN);
}
else
if( ghFocusWnd == lpCInfo->hDirLB ){
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
(LPARAM)0) ){
ErrorMsg(TEXT("MM_SIGN: Filldir failure."));
return 0;
}
}
return 1;
}
case MM_VERIFY: {
if( ghFocusWnd == lpCInfo->hFileLB ) {
RunListBoxItem(lpCInfo, VERIFY);
}
else
if( ghFocusWnd == lpCInfo->hDirLB ){
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
(LPARAM)0) ){
ErrorMsg(TEXT("MM_VERIFY: Filldir failure."));
return 0;
}
}
return 1;
}
case MM_EXPAND:{
lpCInfo->fDirExpand = !lpCInfo->fDirExpand;
if( lpCInfo->fDirExpand )
CheckMenuItem( ghMenu, MM_EXPAND,
MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem( ghMenu, MM_EXPAND,
MF_BYCOMMAND | MF_UNCHECKED);
if( !SendMessage( (HWND)lpCInfo->hwnd, WM_COMMAND,
(WPARAM)MM_REFRESH, (LPARAM)0 ) ){
ErrorMsg(TEXT("MM_EXPAND: MM_REFRESH failure."));
return 0;
}
return 1;
}
//
// refreshes contents of directory and file ListBoxes.
//
case MM_REFRESH:{
DWORD dwThreadID;
INT i, N;
if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
== WAIT_TIMEOUT )
//
// If the full directory expand has been cancled, kill the
// existing thread.
//
if( !lpCInfo->fDirExpand && !lpCInfo->fSuicide){
lpCInfo->fSuicide = TRUE;
return 1;
}
else{
return 0;
}
// if set, clear the expand dir. user abort (escape key) flag.
if( lpCInfo->fEscape ){
lpCInfo->fEscape = FALSE;
ReleaseMutex( lpCInfo->hDirMutex );
return 1;
}
// At this point, the Dir LB mutex has been grabbed.
// Clear directory LB. If expand flag is set, expand all
// directories. Refill File LB.
//
N = GetSize(lpCInfo->DirTable);
for (i = 0; i < N; i++)
TableRemove(lpCInfo->DirTable, 0);
if( SendMessage( lpCInfo->hDirLB, LB_RESETCONTENT,
(WPARAM)0, (LPARAM)0 ) < 0 ){
ErrorMsg(TEXT("Refresh Drv window: Reset Dir LB content failure."));
ReleaseMutex( lpCInfo->hDirMutex );
return 0;
}
//
// This call puts the default root entry back into the empty
// LB. Set suicide flag to false to ensure it will complete.
//
lpCInfo->fSuicide = FALSE;
ExpDir( lpCInfo );
//
// All the Dir LB work is done. Release Dir LB Mutex.
//
ReleaseMutex( lpCInfo->hDirMutex );
if( lpCInfo->fDirExpand ){
CloseHandle( lpCInfo->hDirThread );
lpCInfo->hDirThread = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)FullExpand,
(LPVOID)lpCInfo, 0, &dwThreadID);
if( !lpCInfo->hDirThread ){
ErrorMsg(TEXT("MM_REFRESH: FullExpand CreateThread failure."));
return 0;
}
}
else
ExpDir( lpCInfo );
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLFILE,
(LPARAM)0) ){
ErrorMsg(TEXT("Refresh Drv window: Fillfile failure."));
return 0;
}
return 1;
}
//
// Fill listbox in lParam with directory from Drv child's drive.
// Sent by MM_REFRESH.
//
// lParam == 0
//
case MM_FILLDIR:{
DWORD dwThreadID;
lpCInfo->fSuicide = FALSE;
CloseHandle( lpCInfo->hDirThread );
lpCInfo->hDirThread = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)ExpDir,
(LPVOID)lpCInfo, 0, &dwThreadID);
if( !(lpCInfo->hDirThread) ){
ErrorMsg(TEXT("MM_FILLDIR: ExpDir CreateThread failure."));
return 0;
}
return 1;
}
//
// Fill listbox in lParam with files from current directory.
// Sent by MM_REFRESH & LBN_DBLCLK in DrvWndProc.
//
// lParam == 0
//
case MM_FILLFILE:
ghFocusWnd = lpCInfo->hFileLB;
return FillFile(lpCInfo, hwnd);
break;
//
// The following WM_COMMAND messages are sent by the listboxes
//
// HIWORD(wParam) = LB notification message
// lParam = LB window handle
//
case LISTFILE_ID:{
switch( HIWORD(wParam) ){
//
// In case of double click on a directory, expand the file
// Listbox. if on a file name, run or edit file.
//
case LBN_DBLCLK:{
RunListBoxItem(lpCInfo, ENCRYPT_DECRYPT);
return 1;
}
break;
case LBN_SETFOCUS:{
ghFocusWnd = lpCInfo->hFileLB;
}
break;
default:
return 1;
}
} // LISTFILE_ID
break;
//
// Notification from the Directory ListBox
//
case LISTDIR_ID:{
switch( HIWORD(wParam) ){
case LBN_SETFOCUS:{
ghFocusWnd = lpCInfo->hDirLB;
}
break;
//
// Expand subdirectories in dir listbox
//
case LBN_DBLCLK:{
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
(LPARAM)0) ){
ErrorMsg(TEXT("Dir ListBox Notify: Filldir failure."));
return 0;
}
return 1;
}
break;
case LBN_SELCHANGE:{
//
// for the Directory LB, fill the
// corresp. File LB with items in the newly selected dir.
//
LONG lIndex;
if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
== WAIT_TIMEOUT ){
ErrorMsg(TEXT("Dir LB Notify: Dir LB Mutex Timeout."));
return 0;
}
//
// Retrieve selected (careted) item.
//
lIndex = SendMessage( (HWND)lParam, LB_GETCARETINDEX,
(WPARAM)NULL, (LPARAM)NULL );
if( !ConstructDirName(lpCInfo, lIndex,
lpCInfo->CaptionBarText) ){
ErrorMsg(TEXT("Dir LB Notify: ConstructDirName failure."));
ReleaseMutex( lpCInfo->hDirMutex );
return 0;
}
ReleaseMutex( lpCInfo->hDirMutex );
if( !PostMessage(hwnd, WM_COMMAND, MM_FILLFILE,
(LPARAM)0) ){
ErrorMsg(TEXT("Dir ListBox Notify: Fillfile failure."));
return 0;
}
} // LBN_SELCHANGE
break;
default:
return 1;
}
} // LISTDIR_ID
break;
default:
return 1;
}
}
break;
//
// Whenever the Drv child window is resized, its children has to be
// resized accordingly. The GetWindowLong GWL_USERDATA values
// contain the height of the windows queried, set in their respective
// WM_CREATE cases.
//
case WM_SIZE: {
LPCINFO lpCInfo;
int nListHeight,
nListWidth;
HWND hLeftLB,
hRightLB;
//
// First, get the text window's handle from the per Drv child
// DRVCHILDINFO data structure
//
lpCInfo = (LPCINFO)GetWindowLong(hwnd, GWL_USERDATA);
if (!lpCInfo) {
ErrorMsg(TEXT("DrvWndProc: WM_SIZE: lpCInfo is NULL."));
return 0;
}
nListHeight = HIWORD(lParam) -
GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA)
- LIST_BORDER * 2;
nListWidth = (LOWORD(lParam) - LIST_BORDER) / 2 - LIST_BORDER;
//
// Always, put the text window at the top of the Drv window.
// Increasing sides and bottom extents by 1 to overlap border
// with Drv child border
//
MoveWindow(lpCInfo->hTextWnd,
-1,
0,
LOWORD(lParam) + 2,
GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1,
TRUE);
if( lpCInfo->fDirLeft ){
hLeftLB = lpCInfo->hDirLB;
hRightLB = lpCInfo->hFileLB;
}
else{
hLeftLB = lpCInfo->hFileLB;
hRightLB = lpCInfo->hDirLB;
}
MoveWindow(hLeftLB,
LIST_BORDER,
GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1
+ LIST_BORDER,
nListWidth,
nListHeight,
TRUE);
MoveWindow(hRightLB,
(LOWORD(lParam) + LIST_BORDER) / 2,
GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1
+ LIST_BORDER,
nListWidth,
nListHeight,
TRUE);
break;
}
case WM_PARENTNOTIFY:{
LPCINFO lpCInfo;
if(wParam == WM_LBUTTONDOWN){
lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
if(lpCInfo == NULL){
ErrorMsg(TEXT("Drv child: Parent notify failure."));
return 1;
}
if(HIWORD(wParam) == LISTDIR_ID)
SetFocus(lpCInfo->hDirLB);
else
if(HIWORD(wParam) == LISTFILE_ID)
SetFocus(lpCInfo->hFileLB);
else
if(HIWORD(wParam) == TEXT_WINDOW_ID)
SetFocus(lpCInfo->hTextWnd);
}
break;
}
//
// Same as MainWndProc's MM_ACTIVEDRV case. The initial PostMessage
// is so the currently active Drv child will not process the message
// until it is no longer in focus.
//
case WM_MOUSEACTIVATE:{
LPCINFO lpCInfo;
PostMessage(ghwndDrv, WM_COMMAND, (WPARAM)MM_TOGGLE,
(LPARAM)NULL);
ghwndDrv = hwnd;
SendMessage(ghwndDrv, WM_COMMAND, (WPARAM)MM_TOGGLE,
(LPARAM)NULL);
lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
if (!lpCInfo) {
ErrorMsg(TEXT("DrvWndProc: lpCInfo is NULL."));
return FALSE;
}
SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV,
(LPARAM)lpCInfo->lpDriveInfo);
break;
}
//
// Free the DRVCHILDINFO data that associates with this window
// also, reset the menu.
//
case WM_CLOSE: {
LPCINFO lpCInfo;
lpCInfo = (LPCINFO)GetWindowLong(hwnd, GWL_USERDATA);
if (!lpCInfo) {
ErrorMsg(TEXT("DrvWndProc: WM_CLOSE: lpCInfo is NULL."));
return 0;
}
CloseHandle(lpCInfo->hDirThread);
CloseHandle(lpCInfo->hDirMutex );
CloseHandle(lpCInfo->hFileMutex );
TableFree(lpCInfo->DirTable);
TableFree(lpCInfo->FileTable);
break;
}
// case WM_DELETEITEM:
case WM_DRAWITEM: {
// Get pointer to the DRAWITEMSTRUCT
lpdis = (LPDRAWITEMSTRUCT)lParam;
switch (lpdis->itemAction)
{
case ODA_DRAWENTIRE:
DrawEntireItem(lpdis);
break;
case ODA_SELECT:
HandleSelectionState(lpdis);
break;
}
// Return TRUE meaning that we processed this message.
return 1;
}
case WM_MEASUREITEM:{
lpmis = (LPMEASUREITEMSTRUCT)lParam;
// All the items are the same height since the list box style is
// LBS_OWNERDRAWFIXED
//
lpmis->itemHeight = 15;
return 1;
}
case WM_COMPAREITEM: {
INT cv;
lpcis = (LPCOMPAREITEMSTRUCT)lParam;
if (!lpcis->itemData1)
ErrorMsg(TEXT("WM_COMPAREITEM: lpcis->itemData1 is NULL."));
if (!lpcis->itemData2)
ErrorMsg(TEXT("WM_COMPAREITEM: lpcis->itemData2 is NULL."));
cv = CFilerlstrcmp((LPTSTR)(lpcis->itemData1), (LPTSTR)(lpcis->itemData2));
if (cv < 0)
return -1;
else if (cv == 0)
return 0;
else if (cv > 0)
return 1;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
} //switch
return DefWindowProc(hwnd, message, wParam, lParam);
}
/*************************************************************************************\
* TextWndProc()
*
* Text Window procedure for displaying miscellaneous messages to user.
\*************************************************************************************/
LRESULT WINAPI TextWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HDC hDC;
HGDIOBJ hOldFont;
TEXTMETRIC tm;
LONG lHeight;
hDC = GetDC(hwnd);
hOldFont = SelectObject(hDC, ghFont);
GetTextMetrics(hDC, &tm);
//
// base the height of the window on size of text
//
lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6;
//
// saved the height for later reference
//
SetWindowLong(hwnd, GWL_USERDATA, lHeight);
if(hOldFont)
SelectObject(hDC, hOldFont);
ReleaseDC(hwnd, hDC);
break;
}
case WM_SETTEXT:
DefWindowProc(hwnd, message, wParam, lParam);
if( !InvalidateRect(hwnd, NULL, TRUE) ){
ErrorMsg(TEXT("Textwindow: Set text failure."));
return 1;
}
UpdateWindow(hwnd);
return 1;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
TCHAR ach[BUF_SIZE];
int len, nxBorder, nyBorder;
HFONT hOldFont = NULL;
HBRUSH hBrush;
BeginPaint(hwnd, &ps);
GetClientRect(hwnd,&rc);
len = GetWindowText(hwnd, ach, BUF_SIZE);
SetBkMode(ps.hdc, TRANSPARENT);
if( GetParent(hwnd) == ghwndDrv ){
hBrush = CreateSolidBrush( GetSysColor(COLOR_ACTIVECAPTION) );
SetTextColor( ps.hdc, GetSysColor(COLOR_CAPTIONTEXT) );
}
else{
hBrush = CreateSolidBrush( GetSysColor(COLOR_INACTIVECAPTION) );
SetTextColor( ps.hdc, GetSysColor(COLOR_INACTIVECAPTIONTEXT) );
}
hOldFont = SelectObject(ps.hdc, ghFont);
FillRect(ps.hdc, &rc, hBrush);
nxBorder = GetSystemMetrics(SM_CXBORDER);
rc.left += 9*nxBorder;
rc.right -= 9*nxBorder;
nyBorder = GetSystemMetrics(SM_CYBORDER);
rc.top += 3*nyBorder;
rc.bottom -= 3*nyBorder;
ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
&rc, ach, len, NULL);
SetBkMode(ps.hdc, OPAQUE);
if (hOldFont)
SelectObject(ps.hdc, hOldFont);
DeleteObject(hBrush);
EndPaint(hwnd, &ps);
return 1;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}