📄 filedlg.c
字号:
fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
GetWindowRect( fodInfos->DlgInfos.hwndLookInCB,&rectlook);
MapWindowPoints( 0, hwnd,(LPPOINT)&rectlook,2);
/* construct the toolbar */
GetWindowRect(GetDlgItem(hwnd,IDC_TOOLBARSTATIC),&rectTB);
MapWindowPoints( 0, hwnd,(LPPOINT)&rectTB,2);
rectTB.right = rectlook.right + rectTB.right - rectTB.left;
rectTB.bottom = rectlook.top - 1 + rectTB.bottom - rectTB.top;
rectTB.left = rectlook.right;
rectTB.top = rectlook.top-1;
if (fodInfos->unicode)
fodInfos->DlgInfos.hwndTB = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
rectTB.left, rectTB.top,
rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
else
fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL,
WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
rectTB.left, rectTB.top,
rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
/* FIXME: use TB_LOADIMAGES when implemented */
/* SendMessageW(fodInfos->DlgInfos.hwndTB, TB_LOADIMAGES, IDB_VIEW_SMALL_COLOR, HINST_COMMCTRL);*/
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 12, (LPARAM) &tba[0]);
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 1, (LPARAM) &tba[1]);
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) &tbb);
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
/* Set the window text with the text specified in the OPENFILENAME structure */
if(fodInfos->title)
{
SetWindowTextW(hwnd,fodInfos->title);
}
else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
{
WCHAR buf[16];
LoadStringW(COMDLG32_hInstance, IDS_SAVE, buf, sizeof(buf)/sizeof(WCHAR));
SetWindowTextW(hwnd, buf);
}
/* Initialise the file name edit control */
handledPath = FALSE;
TRACE("Before manipilation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
if(fodInfos->filename)
{
/* 1. If win2000 or higher and filename contains a path, use it
in preference over the lpstrInitialDir */
if (win2000plus && *fodInfos->filename && strpbrkW(fodInfos->filename, szwSlash)) {
WCHAR tmpBuf[MAX_PATH];
WCHAR *nameBit;
DWORD result;
result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit);
if (result) {
/* nameBit is always shorter than the original filename */
lstrcpyW(fodInfos->filename,nameBit);
*nameBit = 0x00;
if (fodInfos->initdir == NULL)
MemFree(fodInfos->initdir);
fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
lstrcpyW(fodInfos->initdir, tmpBuf);
handledPath = TRUE;
TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n",
debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
}
SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
} else {
SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
}
}
/* 2. (All platforms) If initdir is not null, then use it */
if ((handledPath == FALSE) && (fodInfos->initdir!=NULL) &&
(*fodInfos->initdir!=0x00))
{
/* Work out the proper path as supplied one might be relative */
/* (Here because supplying '.' as dir browses to My Computer) */
if (handledPath==FALSE) {
WCHAR tmpBuf[MAX_PATH];
WCHAR tmpBuf2[MAX_PATH];
WCHAR *nameBit;
DWORD result;
lstrcpyW(tmpBuf, fodInfos->initdir);
if( PathFileExistsW(tmpBuf) ) {
/* initdir does not have to be a directory. If a file is
* specified, the dir part is taken */
if( PathIsDirectoryW(tmpBuf)) {
if (tmpBuf[lstrlenW(tmpBuf)-1] != '\\') {
lstrcatW(tmpBuf, szwSlash);
}
lstrcatW(tmpBuf, szwStar);
}
result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
if (result) {
*nameBit = 0x00;
MemFree(fodInfos->initdir);
fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf2) + 1)*sizeof(WCHAR));
lstrcpyW(fodInfos->initdir, tmpBuf2);
handledPath = TRUE;
TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
}
}
else if (fodInfos->initdir)
{
MemFree(fodInfos->initdir);
fodInfos->initdir = NULL;
TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
}
}
}
if ((handledPath == FALSE) && ((fodInfos->initdir==NULL) ||
(*fodInfos->initdir==0x00)))
{
/* 3. All except w2k+: if filename contains a path use it */
if (!win2000plus && fodInfos->filename &&
*fodInfos->filename &&
strpbrkW(fodInfos->filename, szwSlash)) {
WCHAR tmpBuf[MAX_PATH];
WCHAR *nameBit;
DWORD result;
result = GetFullPathNameW(fodInfos->filename, MAX_PATH,
tmpBuf, &nameBit);
if (result) {
int len;
/* nameBit is always shorter than the original filename */
lstrcpyW(fodInfos->filename, nameBit);
*nameBit = 0x00;
len = lstrlenW(tmpBuf);
MemFree(fodInfos->initdir);
fodInfos->initdir = MemAlloc((len+1)*sizeof(WCHAR));
lstrcpyW(fodInfos->initdir, tmpBuf);
handledPath = TRUE;
TRACE("Value in Filename includes path, overriding initdir: %s, %s\n",
debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
}
SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
}
/* 4. win98+ and win2000+ if any files of specified filter types in
current directory, use it */
if ( win98plus && handledPath == FALSE &&
fodInfos->filter && *fodInfos->filter) {
BOOL searchMore = TRUE;
LPCWSTR lpstrPos = fodInfos->filter;
WIN32_FIND_DATAW FindFileData;
HANDLE hFind;
while (searchMore)
{
/* filter is a list... title\0ext\0......\0\0 */
/* Skip the title */
if(! *lpstrPos) break; /* end */
lpstrPos += lstrlenW(lpstrPos) + 1;
/* See if any files exist in the current dir with this extension */
if(! *lpstrPos) break; /* end */
hFind = FindFirstFileW(lpstrPos, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
/* None found - continue search */
lpstrPos += lstrlenW(lpstrPos) + 1;
} else {
searchMore = FALSE;
MemFree(fodInfos->initdir);
fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
handledPath = TRUE;
TRACE("No initial dir specified, but files of type %s found in current, so using it\n",
debugstr_w(lpstrPos));
break;
}
}
}
/* 5. Win2000+: FIXME: Next, Recently used? Not sure how windows does this */
/* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
if (handledPath == FALSE && (win2000plus || win98plus)) {
fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
if(FAILED(COMDLG32_SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir)))
{
if(FAILED(COMDLG32_SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir)))
{
/* last fallback */
GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
} else {
TRACE("No personal dir, using desktop instead: %s\n", debugstr_w(fodInfos->initdir));
}
} else {
TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
}
handledPath = TRUE;
} else if (handledPath==FALSE) {
fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
handledPath = TRUE;
TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir));
}
}
SetFocus(GetDlgItem(hwnd, IDC_FILENAME));
TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
/* Must the open as read only check box be checked ?*/
if(fodInfos->ofnInfos->Flags & OFN_READONLY)
{
SendDlgItemMessageW(hwnd,IDC_OPENREADONLY,BM_SETCHECK,TRUE,0);
}
/* Must the open as read only check box be hidden? */
if(fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY)
{
ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
EnableWindow(GetDlgItem(hwnd, IDC_OPENREADONLY), FALSE);
}
/* Must the help button be hidden? */
if (!(fodInfos->ofnInfos->Flags & OFN_SHOWHELP))
{
ShowWindow(GetDlgItem(hwnd, pshHelp), SW_HIDE);
EnableWindow(GetDlgItem(hwnd, pshHelp), FALSE);
}
/* change Open to Save */
if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
{
WCHAR buf[16];
LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, sizeof(buf)/sizeof(WCHAR));
SetDlgItemTextW(hwnd, IDOK, buf);
LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, sizeof(buf)/sizeof(WCHAR));
SetDlgItemTextW(hwnd, IDC_LOOKINSTATIC, buf);
}
return 0;
}
/***********************************************************************
* FILEDLG95_ResizeControls
*
* WM_INITDIALOG message handler (after hook notification)
*/
static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam;
if (fodInfos->DlgInfos.hwndCustomDlg)
{
RECT rc;
UINT flags = SWP_NOACTIVATE;
ArrangeCtrlPositions(fodInfos->DlgInfos.hwndCustomDlg, hwnd,
(fodInfos->ofnInfos->Flags & (OFN_HIDEREADONLY | OFN_SHOWHELP)) == OFN_HIDEREADONLY);
/* resize the custom dialog to the parent size */
if (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))
GetClientRect(hwnd, &rc);
else
{
/* our own fake template is zero sized and doesn't have children, so
* there is no need to resize it. Picasa depends on it.
*/
flags |= SWP_NOSIZE;
SetRectEmpty(&rc);
}
SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
0, 0, rc.right, rc.bottom, flags);
}
else
{
/* Resize the height, if open as read only checkbox ad help button are
* hidden and we are not using a custom template nor a customDialog
*/
if ( (fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY) &&
(!(fodInfos->ofnInfos->Flags &
(OFN_SHOWHELP|OFN_ENABLETEMPLATE|OFN_ENABLETEMPLATEHANDLE))))
{
RECT rectDlg, rectHelp, rectCancel;
GetWindowRect(hwnd, &rectDlg);
GetWindowRect(GetDlgItem(hwnd, pshHelp), &rectHelp);
GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rectCancel);
/* subtract the height of the help button plus the space between the help
* button and the cancel button to the height of the dialog
*/
SetWindowPos(hwnd, 0, 0, 0, rectDlg.right-rectDlg.left,
(rectDlg.bottom-rectDlg.top) - (rectHelp.bottom - rectCancel.bottom),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
}
}
return TRUE;
}
/***********************************************************************
* FILEDLG95_FillControls
*
* WM_INITDIALOG message handler (after hook notification)
*/
static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
LPITEMIDLIST pidlItemId = NULL;
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam;
TRACE("dir=%s file=%s\n",
debugstr_w(fodInfos->initdir), debugstr_w(fodInfos->filename));
/* Get the initial directory pidl */
if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->initdir)))
{
WCHAR path[MAX_PATH];
GetCurrentDirectoryW(MAX_PATH,path);
pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder, path);
}
/* Initialise shell objects */
FILEDLG95_SHELL_Init(hwnd);
/* Initialize the Look In combo box */
FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
/* Initialize the filter combo box */
FILEDLG95_FILETYPE_Init(hwnd);
/* Browse to the initial directory */
IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
/* Free pidlItem memory */
COMDLG32_SHFree(pidlItemId);
return TRUE;
}
/***********************************************************************
* FILEDLG95_Clean
*
* Regroups all the cleaning functions of the filedlg
*/
void FILEDLG95_Clean(HWND hwnd)
{
FILEDLG95_FILETYPE_Clean(hwnd);
FILEDLG95_LOOKIN_Clean(hwnd);
FILEDLG95_SHELL_Clean(hwnd);
}
/***********************************************************************
* FILEDLG95_OnWMCommand
*
* WM_COMMAND message handler
*/
static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
WORD wNotifyCode = HIWORD(wParam); /* notification code */
WORD wID = LOWORD(wParam); /* item, control, or accelerator identifier */
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
switch(wID)
{
/* OK button */
case IDOK:
FILEDLG95_OnOpen(hwnd);
break;
/* Cancel button */
case IDCANCEL:
FILEDLG95_Clean(hwnd);
EndDialog(hwnd, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -