📄 listnet.cpp
字号:
//======================================================================
// ListNet - A network demo application for Windows CE
//
// Written for the book Programming Windows CE
// Copyright (C) 2007 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <winnetwk.h> // Network includes
#include "ListNet.h" // Program-specific stuff
#if defined(WIN32_PLATFORM_PSPC)
#include <aygshell.h> // Add new shell includes.
#pragma comment( lib, "aygshell" ) // Link new shell lib for menu bar.
#endif
// Work around bug in initial version of CE 6
#if _WIN32_WCE == 0x600
#define CE6_BUGFIX
#endif
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT ("ListNet");
HINSTANCE hInst; // Program instance handle
BOOL fFirst = TRUE;
// Command Message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] = {
IDOK, DoMainCommandExit,
IDCANCEL, DoMainCommandExit,
IDD_NETLIST, DoMainCommandViewDrive,
IDD_CNCT, DoMainCommandMapDrive,
IDD_DCNCT, DoMainCommandFreeDrive,
};
//======================================================================
//
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
// Save program instance handle in global variable.
hInst = hInstance;
// Create main window.
DialogBox (hInst, szAppName, NULL, MainWndProc);
return 0;
}
//======================================================================
// Message handling procedures for main window
//----------------------------------------------------------------------
// MainWndProc - Callback function for application window
//
BOOL CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
// With only two messages, do it the old-fashioned way.
switch (wMsg) {
case WM_INITDIALOG:
#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
// For Windows Mobile devices, allow only one instance of the app
SHINITDLGINFO di;
SHMENUBARINFO mbi; // For Win Mobile, create
memset(&mbi, 0, sizeof(SHMENUBARINFO)); // menu bar so that we
mbi.cbSize = sizeof(SHMENUBARINFO); // have a sip button.
mbi.hwndParent = hWnd;
mbi.dwFlags = SHCMBF_EMPTYBAR;
SHCreateMenuBar(&mbi);
di.dwMask = SHIDIM_FLAGS;
di.hDlg = hWnd;
di.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLG;
SHInitDialog (&di);
#endif
i = 75;
SendDlgItemMessage (hWnd, IDD_NETLIST, LB_SETTABSTOPS, 1,
(LPARAM)&i);
RefreshLocalNetDrives (hWnd);
break;
case WM_COMMAND:
return DoCommandMain (hWnd, wMsg, wParam, lParam);
}
return FALSE;
}
//----------------------------------------------------------------------
// DoCommandMain - Process WM_COMMAND message for window.
//
BOOL DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam){
WORD idItem, wNotifyCode;
HWND hwndCtl;
INT i;
// Parse the parameters.
idItem = (WORD) LOWORD (wParam);
wNotifyCode = (WORD) HIWORD (wParam);
hwndCtl = (HWND) lParam;
// Call routine to handle control message.
for (i = 0; i < dim(MainCommandItems); i++) {
if (idItem == MainCommandItems[i].Code) {
(*MainCommandItems[i].Fxn)(hWnd, idItem, hwndCtl,
wNotifyCode);
return TRUE;
}
}
return FALSE;
}
//======================================================================
// Command handler routines
//----------------------------------------------------------------------
// DoMainCommandExit - Process Program Exit command.
//
LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
EndDialog (hWnd, 0);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandViewDrive - Process list box double clicks.
//
LPARAM DoMainCommandViewDrive (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
TCHAR szCmdLine[128], szFolder[MAX_PATH];
PROCESS_INFORMATION pi;
HCURSOR hOld;
INT i, rc, nLen;
// We抮e only interested in list box double-clicks.
if (wNotifyCode != LBN_DBLCLK)
return 0;
i = SendMessage (hwndCtl, LB_GETCURSEL, 0, 0);
if (i == LB_ERR) return 0;
nLen = SendMessage (hwndCtl, LB_GETTEXT, i, (LPARAM)szFolder);
if (nLen == LB_ERR)
return 0;
// Trim off description of share.
for (i = 0; i < nLen; i++)
if (szFolder[i] == TEXT ('\t'))
break;
szFolder[i] = TEXT ('\0');
hOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
wsprintf (szCmdLine, TEXT("\\network\\%s"), szFolder);
rc = CreateProcess (TEXT ("Explorer"), szCmdLine, NULL, NULL,
FALSE, 0, NULL, NULL, NULL, &pi);
if (rc) {
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
SetCursor (hOld);
return TRUE;
}
//----------------------------------------------------------------------
// DoMainCommandMapDrive - Process map network drive command.
//
LPARAM DoMainCommandMapDrive (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
DWORD rc = WS_EX_CONTEXTHELP;
CONNECTDLGSTRUCT cds;
NETRESOURCE nr;
TCHAR szRmt[256];
memset (&nr, 0, sizeof (nr));
nr.dwType = RESOURCETYPE_DISK;
memset (szRmt, 0, sizeof (szRmt));
memset (&cds, 0, sizeof (cds));
cds.cbStructure = sizeof (cds);
cds.hwndOwner = hWnd;
cds.lpConnRes = &nr;
cds.dwFlags = CONNDLG_PERSIST;
// Display dialog box.
#ifdef CE6_BUGFIX
rc = MyWNetConnectionDialog1 (&cds);
#else
rc = WNetConnectionDialog1 (&cds);
#endif
if (rc == NO_ERROR)
RefreshLocalNetDrives (hWnd);
else
CheckErrorCode (hWnd, rc, TEXT ("WNetConnectionDialog1"));
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandFreeDrive - Process disconnect network drive command.
//
LPARAM DoMainCommandFreeDrive (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
int rc = WNetDisconnectDialog (hWnd, RESOURCETYPE_DISK);
if (rc == NO_ERROR)
RefreshLocalNetDrives (hWnd);
else
CheckErrorCode (hWnd, rc, TEXT ("WnetDisconnectDialog"));
return 0;
}
//======================================================================
// Network browsing functions
//----------------------------------------------------------------------
// EnumerateLocalNetDrives - Add an item to the list view control.
//
INT RefreshLocalNetDrives (HWND hWnd) {
HWND hwndCtl = GetDlgItem (hWnd, IDD_NETLIST);
INT rc, nBuffSize = 1024;
DWORD dwCnt, dwSize;
HANDLE hEnum;
LPNETRESOURCE pnr;
PBYTE pPtr, pNew;
TCHAR szText[256];
SendMessage (hwndCtl, LB_RESETCONTENT, 0, 0);
// Allocate buffer for enumeration data.
pPtr = (PBYTE) LocalAlloc (LPTR, nBuffSize);
if (!pPtr)
return -1;
// Start enumeration.
rc = WNetOpenEnum (RESOURCE_REMEMBERED, RESOURCETYPE_ANY, 0, 0,
&hEnum);
if (rc != NO_ERROR) return -1;
// Enumerate one item per loop.
do {
dwCnt = 1;
dwSize = nBuffSize;
rc = WNetEnumResource (hEnum, &dwCnt, pPtr, &dwSize);
if (rc == NO_ERROR) {
pnr = (NETRESOURCE *)pPtr;
StringCchCopy (szText, dim (szText), pnr->lpLocalName);
// Process returned data.
if (rc == NO_ERROR) {
switch (pnr->dwType) {
case RESOURCETYPE_ANY:
StringCchCat (szText, dim (szText), TEXT ("\t Share"));
break;
case RESOURCETYPE_PRINT:
StringCchCat (szText, dim (szText), TEXT ("\t Printer"));
break;
case RESOURCETYPE_DISK:
StringCchCat (szText, dim (szText), TEXT ("\t Disk"));
break;
}
SendMessage (hwndCtl, LB_ADDSTRING, 0, (LPARAM)szText);
// If our buffer was too small, try again.
} else if (rc == ERROR_MORE_DATA) {
pNew = (PBYTE)LocalReAlloc (pPtr, dwSize, LMEM_MOVEABLE);
if (pNew) {
pPtr = pNew;
nBuffSize = LocalSize (pPtr);
rc = 0;
} else
break;
}
}
} while (rc == 0);
// Clean up.
WNetCloseEnum (hEnum);
LocalFree (pPtr);
return 0;
}
//----------------------------------------------------------------------
// CheckErrorCode - Print error messages as necessary.
//
int CheckErrorCode (HWND hWnd, int rc, LPTSTR lpText) {
TCHAR szTxt[128];
// If good or dialog canceled, just return.
if ((rc == NO_ERROR) || (rc == -1))
return rc;
if (rc == ERROR_NO_NETWORK)
StringCchCat (szTxt, dim (szTxt), TEXT ("No network detected."));
else
wsprintf (szTxt, TEXT ("%s failed rc = %d"), lpText, rc);
MessageBox (hWnd, szTxt, szAppName, MB_OK);
return rc;
}
//======================================================================
// My Network Connection Dialog procedure
//
BOOL CALLBACK MyNetConnDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
LPCONNECTDLGSTRUCT lpCDS;
LPNETRESOURCE lpNR;
BOOL bReadOnly = FALSE;
switch (wMsg) {
case WM_INITDIALOG:
if (!lParam) {
EndDialog (hWnd, -2);
return 0;
}
// Save the structure ptr
SetWindowLong (hWnd, GWL_USERDATA, lParam);
// Get what we need from the structure
bReadOnly = ((LPCONNECTDLGSTRUCT)lParam)->dwFlags & CONNDLG_RO_PATH;
lpNR = ((LPCONNECTDLGSTRUCT)lParam)->lpConnRes;
// Init the fields in the dialog box
SetDlgItemText (hWnd, IDD_SHARENAME, lpNR->lpRemoteName);
SetDlgItemText (hWnd, IDD_LOCALNAME, lpNR->lpLocalName);
// If remote name specified, make that field read-only
if (lpNR->lpRemoteName[0] && bReadOnly) {
SendDlgItemMessage (hWnd, IDD_SHARENAME, EM_SETREADONLY, 1, 0);
SetFocus (GetDlgItem (hWnd, IDD_LOCALNAME));
}
else
SetFocus (GetDlgItem (hWnd, IDD_SHARENAME));
return FALSE;
case WM_COMMAND:
switch (LOWORD (wParam)) {
case IDOK:
lpCDS = (LPCONNECTDLGSTRUCT)GetWindowLong (hWnd,
GWL_USERDATA);
lpNR = lpCDS->lpConnRes;
GetDlgItemText (hWnd, IDD_SHARENAME,
lpNR->lpRemoteName, MAX_PATH);
GetDlgItemText (hWnd, IDD_LOCALNAME,
lpNR->lpLocalName, MAX_PATH);
// Unlike CE's version, I don't auto-create a
// local share name.
if ((lpNR->lpLocalName[0] == TEXT('\0')) ||
(lpNR->lpLocalName[0] == TEXT('*'))) {
MessageBox (hWnd, TEXT("Please enter a local name"),
TEXT("Network"), MB_OK);
return TRUE;
}
EndDialog (hWnd, 0);
return TRUE;
case IDCANCEL:
EndDialog (hWnd, -1);
return TRUE;
}
break;
}
return FALSE;
}
//----------------------------------------------------------------------
// MyWNetConnectionDialog1 - My version of the network connection dlg
//
DWORD MyWNetConnectionDialog1 (LPCONNECTDLGSTRUCT lpConnDlgStruct) {
DWORD rc, dwFlags = 0;
HWND hParent = NULL;
TCHAR szLocal[MAX_PATH];
TCHAR szRmt[MAX_PATH];
// Parameter checking
if ((lpConnDlgStruct == 0) ||
(lpConnDlgStruct->cbStructure != sizeof (CONNECTDLGSTRUCT)) ||
(lpConnDlgStruct->lpConnRes == 0) ||
(lpConnDlgStruct->lpConnRes->dwType != RESOURCETYPE_DISK) ||
// can't have both persist and non-persist flags set
(((lpConnDlgStruct->dwFlags & CONNDLG_PERSIST) &&
(lpConnDlgStruct->dwFlags & CONNDLG_NOT_PERSIST)))) {
return ERROR_INVALID_PARAMETER;
}
szLocal[0] = TEXT('\0');
szRmt[0] = TEXT('\0');
lpConnDlgStruct->lpConnRes->lpRemoteName = szRmt;
lpConnDlgStruct->lpConnRes->lpLocalName = szLocal;
// If specified, copy over strings
if ((lpConnDlgStruct->lpConnRes->lpRemoteName != 0) &&
(lpConnDlgStruct->lpConnRes->lpRemoteName[0] != TEXT('\0')))
StringCchCopy (szRmt, dim (szRmt),
lpConnDlgStruct->lpConnRes->lpRemoteName);
if ((lpConnDlgStruct->lpConnRes->lpLocalName != 0) &&
(lpConnDlgStruct->lpConnRes->lpLocalName[0] != TEXT('\0')))
StringCchCopy (szLocal, dim (szLocal),
lpConnDlgStruct->lpConnRes->lpLocalName);
// Display the dialog box
rc = DialogBoxParam (hInst, TEXT("MyConnDlg"), hParent,
MyNetConnDlgProc, (LPARAM)lpConnDlgStruct);
if (rc == 0) {
// The 'real' function always persists the link
if (lpConnDlgStruct->dwFlags & CONNDLG_PERSIST)
dwFlags = CONNECT_UPDATE_PROFILE;
// Make the connection
rc = WNetAddConnection3 (lpConnDlgStruct->hwndOwner,
lpConnDlgStruct->lpConnRes, NULL, NULL,
dwFlags);
}
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -