Fix 16/32 bit separation.
This commit is contained in:
parent
4bbc1b3fb6
commit
4d80215062
|
@ -13,15 +13,16 @@ C_SRCS = \
|
|||
cdlg32.c \
|
||||
colordlg.c \
|
||||
filedlg.c \
|
||||
filedlg16.c \
|
||||
filedlg31.c \
|
||||
filedlgbrowser.c \
|
||||
finddlg32.c \
|
||||
filetitle.c \
|
||||
finddlg32.c \
|
||||
fontdlg.c \
|
||||
printdlg.c
|
||||
|
||||
C_SRCS16 = \
|
||||
colordlg16.c \
|
||||
filedlg16.c \
|
||||
finddlg.c \
|
||||
fontdlg16.c \
|
||||
generic.c \
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "commdlg.h"
|
||||
#include "dlgs.h"
|
||||
#include "cdlg.h"
|
||||
#include "filedlg31.h"
|
||||
#include "wine/debug.h"
|
||||
#include "cderr.h"
|
||||
#include "shellapi.h"
|
||||
|
@ -104,6 +105,11 @@ typedef struct tagLookInInfo
|
|||
UINT uSelectedItem;
|
||||
} LookInInfos;
|
||||
|
||||
typedef struct tagFD32_PRIVATE
|
||||
{
|
||||
OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */
|
||||
} FD32_PRIVATE, *PFD32_PRIVATE;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Defines and global variables
|
||||
|
@ -223,10 +229,6 @@ HRESULT FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam
|
|||
BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed);
|
||||
static BOOL BrowseSelectedFolder(HWND hwnd);
|
||||
|
||||
/* old style dialogs */
|
||||
extern BOOL GetFileName31A(LPOPENFILENAMEA lpofn, UINT dlgType);
|
||||
extern BOOL GetFileName31W(LPOPENFILENAMEW lpofn, UINT dlgType);
|
||||
|
||||
/***********************************************************************
|
||||
* GetFileName95
|
||||
*
|
||||
|
@ -3272,6 +3274,321 @@ static void MemFree(void *mem)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Old-style (win3.1) dialogs */
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_GetTemplate [internal]
|
||||
*
|
||||
* Get a template (or FALSE if failure) when 16 bits dialogs are used
|
||||
* by a 32 bits application
|
||||
*
|
||||
*/
|
||||
static BOOL FD32_GetTemplate(PFD31_DATA lfs)
|
||||
{
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632;
|
||||
HANDLE hDlgTmpl;
|
||||
|
||||
if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
|
||||
{
|
||||
if (!(lfs->template = LockResource( ofnW->hInstance )))
|
||||
{
|
||||
COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (ofnW->Flags & OFN_ENABLETEMPLATE)
|
||||
{
|
||||
HRSRC hResInfo;
|
||||
if (priv->ofnA)
|
||||
hResInfo = FindResourceA(priv->ofnA->hInstance,
|
||||
priv->ofnA->lpTemplateName,
|
||||
(LPSTR)RT_DIALOG);
|
||||
else
|
||||
hResInfo = FindResourceW(ofnW->hInstance,
|
||||
ofnW->lpTemplateName,
|
||||
(LPWSTR)RT_DIALOG);
|
||||
if (!hResInfo)
|
||||
{
|
||||
COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
|
||||
hResInfo)) ||
|
||||
!(lfs->template = LockResource(hDlgTmpl)))
|
||||
{
|
||||
COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
} else { /* get it from internal Wine resource */
|
||||
HRSRC hResInfo;
|
||||
if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
|
||||
lfs->open? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
|
||||
{
|
||||
COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
|
||||
!(lfs->template = LockResource( hDlgTmpl )))
|
||||
{
|
||||
COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* FD32_Init [internal]
|
||||
* called from the common 16/32 code to initialize 32 bit data
|
||||
*/
|
||||
static BOOL CALLBACK FD32_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data)
|
||||
{
|
||||
BOOL IsUnicode = (BOOL) data;
|
||||
PFD32_PRIVATE priv;
|
||||
|
||||
priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FD32_PRIVATE));
|
||||
lfs->private1632 = priv;
|
||||
if (NULL == lfs->private1632) return FALSE;
|
||||
if (IsUnicode)
|
||||
{
|
||||
lfs->ofnW = *((LPOPENFILENAMEW) lParam);
|
||||
if (lfs->ofnW.Flags & OFN_ENABLEHOOK)
|
||||
if (lfs->ofnW.lpfnHook)
|
||||
lfs->hook = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->ofnA = (LPOPENFILENAMEA) lParam;
|
||||
if (priv->ofnA->Flags & OFN_ENABLEHOOK)
|
||||
if (priv->ofnA->lpfnHook)
|
||||
lfs->hook = TRUE;
|
||||
FD31_MapOfnStructA(priv->ofnA, &lfs->ofnW, lfs->open);
|
||||
}
|
||||
|
||||
if (! FD32_GetTemplate(lfs)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_CallWindowProc [internal]
|
||||
*
|
||||
* called from the common 16/32 code to call the appropriate hook
|
||||
*/
|
||||
BOOL CALLBACK FD32_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632;
|
||||
|
||||
if (priv->ofnA)
|
||||
{
|
||||
return (BOOL) CallWindowProcA(
|
||||
(WNDPROC)priv->ofnA->lpfnHook, lfs->hwnd,
|
||||
wMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
return (BOOL) CallWindowProcW(
|
||||
(WNDPROC)lfs->ofnW.lpfnHook, lfs->hwnd,
|
||||
wMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_UpdateResult [internal]
|
||||
* update the real client structures if any
|
||||
*/
|
||||
static void CALLBACK FD32_UpdateResult(PFD31_DATA lfs)
|
||||
{
|
||||
PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632;
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
|
||||
if (priv->ofnA)
|
||||
{
|
||||
if (ofnW->nMaxFile &&
|
||||
!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1,
|
||||
priv->ofnA->lpstrFile, ofnW->nMaxFile, NULL, NULL ))
|
||||
priv->ofnA->lpstrFile[ofnW->nMaxFile-1] = 0;
|
||||
priv->ofnA->nFileOffset = ofnW->nFileOffset;
|
||||
priv->ofnA->nFileExtension = ofnW->nFileExtension;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_UpdateFileTitle [internal]
|
||||
* update the real client structures if any
|
||||
*/
|
||||
static void CALLBACK FD32_UpdateFileTitle(PFD31_DATA lfs)
|
||||
{
|
||||
PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632;
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
|
||||
if (priv->ofnA)
|
||||
{
|
||||
if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1,
|
||||
priv->ofnA->lpstrFileTitle, ofnW->nMaxFileTitle, NULL, NULL ))
|
||||
priv->ofnA->lpstrFileTitle[ofnW->nMaxFileTitle-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_SendLbGetCurSel [internal]
|
||||
* retrieve selected listbox item
|
||||
*/
|
||||
static LRESULT CALLBACK FD32_SendLbGetCurSel(PFD31_DATA lfs)
|
||||
{
|
||||
return SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* FD32_Destroy [internal]
|
||||
* called from the common 16/32 code to cleanup 32 bit data
|
||||
*/
|
||||
static void CALLBACK FD32_Destroy(PFD31_DATA lfs)
|
||||
{
|
||||
PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632;
|
||||
|
||||
/* if ofnW has been allocated, have to free everything in it */
|
||||
if (NULL != priv && NULL != priv->ofnA)
|
||||
FD31_FreeOfnW(&lfs->ofnW);
|
||||
}
|
||||
|
||||
static void FD32_SetupCallbacks(PFD31_CALLBACKS callbacks)
|
||||
{
|
||||
callbacks->Init = FD32_Init;
|
||||
callbacks->CWP = FD32_CallWindowProc;
|
||||
callbacks->UpdateResult = FD32_UpdateResult;
|
||||
callbacks->UpdateFileTitle = FD32_UpdateFileTitle;
|
||||
callbacks->SendLbGetCurSel = FD32_SendLbGetCurSel;
|
||||
callbacks->Destroy = FD32_Destroy;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD32_WMMeasureItem [internal]
|
||||
*/
|
||||
static LONG FD32_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LPMEASUREITEMSTRUCT lpmeasure;
|
||||
|
||||
lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
|
||||
lpmeasure->itemHeight = FD31_GetFldrHeight();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FileOpenDlgProc [internal]
|
||||
* Used for open and save, in fact.
|
||||
*/
|
||||
static INT_PTR CALLBACK FD32_FileOpenDlgProc(HWND hWnd, UINT wMsg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PFD31_DATA lfs = (PFD31_DATA)GetPropA(hWnd,FD31_OFN_PROP);
|
||||
|
||||
TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
|
||||
if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
|
||||
{
|
||||
INT_PTR lRet;
|
||||
lRet = (INT_PTR)FD31_CallWindowProc(lfs, wMsg, wParam, lParam);
|
||||
if (lRet)
|
||||
return lRet; /* else continue message processing */
|
||||
}
|
||||
switch (wMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
return FD31_WMInitDialog(hWnd, wParam, lParam);
|
||||
|
||||
case WM_MEASUREITEM:
|
||||
return FD32_WMMeasureItem(hWnd, wParam, lParam);
|
||||
|
||||
case WM_DRAWITEM:
|
||||
return FD31_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
|
||||
|
||||
case WM_COMMAND:
|
||||
return FD31_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
|
||||
#if 0
|
||||
case WM_CTLCOLOR:
|
||||
SetBkColor((HDC16)wParam, 0x00C0C0C0);
|
||||
switch (HIWORD(lParam))
|
||||
{
|
||||
case CTLCOLOR_BTN:
|
||||
SetTextColor((HDC16)wParam, 0x00000000);
|
||||
return hGRAYBrush;
|
||||
case CTLCOLOR_STATIC:
|
||||
SetTextColor((HDC16)wParam, 0x00000000);
|
||||
return hGRAYBrush;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetFileName31A [internal]
|
||||
*
|
||||
* Creates a win31 style dialog box for the user to select a file to open/save.
|
||||
*/
|
||||
static BOOL GetFileName31A(LPOPENFILENAMEA lpofn, /* addess of structure with data*/
|
||||
UINT dlgType /* type dialogue : open/save */
|
||||
)
|
||||
{
|
||||
HINSTANCE hInst;
|
||||
BOOL bRet = FALSE;
|
||||
PFD31_DATA lfs;
|
||||
FD31_CALLBACKS callbacks;
|
||||
|
||||
if (!lpofn || !FD31_Init()) return FALSE;
|
||||
|
||||
TRACE("ofn flags %08lx\n", lpofn->Flags);
|
||||
FD32_SetupCallbacks(&callbacks);
|
||||
lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, &callbacks, (DWORD) FALSE);
|
||||
if (lfs)
|
||||
{
|
||||
hInst = (HINSTANCE)GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
|
||||
bRet = DialogBoxIndirectParamA( hInst, lfs->template, lpofn->hwndOwner,
|
||||
FD32_FileOpenDlgProc, (LPARAM)lfs);
|
||||
FD31_DestroyPrivate(lfs);
|
||||
}
|
||||
|
||||
TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetFileName31W [internal]
|
||||
*
|
||||
* Creates a win31 style dialog box for the user to select a file to open/save
|
||||
*/
|
||||
static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* addess of structure with data*/
|
||||
UINT dlgType /* type dialogue : open/save */
|
||||
)
|
||||
{
|
||||
HINSTANCE hInst;
|
||||
BOOL bRet = FALSE;
|
||||
PFD31_DATA lfs;
|
||||
FD31_CALLBACKS callbacks;
|
||||
|
||||
if (!lpofn || !FD31_Init()) return FALSE;
|
||||
|
||||
FD32_SetupCallbacks(&callbacks);
|
||||
lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, &callbacks, (DWORD) FALSE);
|
||||
if (lfs)
|
||||
{
|
||||
hInst = (HINSTANCE)GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
|
||||
bRet = DialogBoxIndirectParamW( hInst, lfs->template, lpofn->hwndOwner,
|
||||
FD32_FileOpenDlgProc, (LPARAM)lfs);
|
||||
FD31_DestroyPrivate(lfs);
|
||||
}
|
||||
|
||||
TRACE("return lpstrFile=%s !\n", debugstr_w(lpofn->lpstrFile));
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/* ------------------ APIs ---------------------- */
|
||||
|
||||
/***********************************************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,931 @@
|
|||
/*
|
||||
* COMMDLG - File Dialogs
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1996 Albrecht Kleine
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
#include "cderr.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
#include "winuser.h"
|
||||
#include "commdlg.h"
|
||||
#include "cderr.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
|
||||
|
||||
#include "cdlg.h"
|
||||
#include "filedlg31.h"
|
||||
|
||||
#define BUFFILE 512
|
||||
#define BUFFILEALLOC 512 * sizeof(WCHAR)
|
||||
|
||||
static const WCHAR FILE_star[] = {'*','.','*', 0};
|
||||
static const WCHAR FILE_bslash[] = {'\\', 0};
|
||||
static const WCHAR FILE_specc[] = {'%','c',':', 0};
|
||||
static const int fldrHeight = 16;
|
||||
static const int fldrWidth = 20;
|
||||
|
||||
static HICON hFolder = 0;
|
||||
static HICON hFolder2 = 0;
|
||||
static HICON hFloppy = 0;
|
||||
static HICON hHDisk = 0;
|
||||
static HICON hCDRom = 0;
|
||||
static HICON hNet = 0;
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_Init [internal]
|
||||
*/
|
||||
BOOL FD31_Init(void)
|
||||
{
|
||||
static BOOL initialized = 0;
|
||||
|
||||
if (!initialized) {
|
||||
hFolder = LoadImageA( COMDLG32_hInstance, "FOLDER", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
hFolder2 = LoadImageA( COMDLG32_hInstance, "FOLDER2", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
hFloppy = LoadImageA( COMDLG32_hInstance, "FLOPPY", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
hHDisk = LoadImageA( COMDLG32_hInstance, "HDISK", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
hCDRom = LoadImageA( COMDLG32_hInstance, "CDROM", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
hNet = LoadImageA( COMDLG32_hInstance, "NETWORK", IMAGE_ICON, 16, 16, LR_SHARED );
|
||||
if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
|
||||
hHDisk == 0 || hCDRom == 0 || hNet == 0)
|
||||
{
|
||||
ERR("Error loading icons !\n");
|
||||
return FALSE;
|
||||
}
|
||||
initialized = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_StripEditControl [internal]
|
||||
* Strip pathnames off the contents of the edit control.
|
||||
*/
|
||||
static void FD31_StripEditControl(HWND hwnd)
|
||||
{
|
||||
WCHAR temp[BUFFILE], *cp;
|
||||
|
||||
GetDlgItemTextW( hwnd, edt1, temp, sizeof(temp)/sizeof(WCHAR));
|
||||
cp = strrchrW(temp, '\\');
|
||||
if (cp != NULL) {
|
||||
strcpyW(temp, cp+1);
|
||||
}
|
||||
cp = strrchrW(temp, ':');
|
||||
if (cp != NULL) {
|
||||
strcpyW(temp, cp+1);
|
||||
}
|
||||
/* FIXME: shouldn't we do something with the result here? ;-) */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_CallWindowProc [internal]
|
||||
*
|
||||
* Call the appropriate hook
|
||||
*/
|
||||
BOOL FD31_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
return lfs->callbacks->CWP(lfs, wMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_ScanDir [internal]
|
||||
*/
|
||||
static BOOL FD31_ScanDir(HWND hWnd, LPWSTR newPath)
|
||||
{
|
||||
WCHAR buffer[BUFFILE];
|
||||
HWND hdlg, hdlgDir;
|
||||
LRESULT lRet = TRUE;
|
||||
HCURSOR hCursorWait, oldCursor;
|
||||
|
||||
TRACE("Trying to change to %s\n", debugstr_w(newPath));
|
||||
if ( newPath[0] && !SetCurrentDirectoryW( newPath ))
|
||||
return FALSE;
|
||||
lstrcpynW(buffer, newPath, sizeof(buffer)/sizeof(WCHAR));
|
||||
|
||||
/* get the list of spec files */
|
||||
GetDlgItemTextW(hWnd, edt1, buffer, sizeof(buffer)/sizeof(WCHAR));
|
||||
|
||||
hCursorWait = LoadCursorA(0, (LPSTR)IDC_WAIT);
|
||||
oldCursor = SetCursor(hCursorWait);
|
||||
|
||||
/* list of files */
|
||||
if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) {
|
||||
WCHAR* scptr; /* ptr on semi-colon */
|
||||
WCHAR* filter = buffer;
|
||||
|
||||
TRACE("Using filter %s\n", debugstr_w(filter));
|
||||
SendMessageW(hdlg, LB_RESETCONTENT, 0, 0);
|
||||
while (filter) {
|
||||
scptr = strchrW(filter, ';');
|
||||
if (scptr) *scptr = 0;
|
||||
while (*filter == ' ') filter++;
|
||||
TRACE("Using file spec %s\n", debugstr_w(filter));
|
||||
if (SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
|
||||
return FALSE;
|
||||
if (scptr) *scptr = ';';
|
||||
filter = (scptr) ? (scptr + 1) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* list of directories */
|
||||
strcpyW(buffer, FILE_star);
|
||||
|
||||
if ((hdlgDir = GetDlgItem(hWnd, lst2)) != 0) {
|
||||
lRet = DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
|
||||
}
|
||||
SetCursor(oldCursor);
|
||||
return lRet;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_GetFileType [internal]
|
||||
*/
|
||||
|
||||
static LPWSTR FD31_GetFileType(LPWSTR cfptr, LPWSTR fptr, WORD index)
|
||||
{
|
||||
int n, i;
|
||||
i = 0;
|
||||
if (cfptr)
|
||||
for ( ;(n = lstrlenW(cfptr)) != 0; i++)
|
||||
{
|
||||
cfptr += n + 1;
|
||||
if (i == index)
|
||||
return cfptr;
|
||||
cfptr += lstrlenW(cfptr) + 1;
|
||||
}
|
||||
if (fptr)
|
||||
for ( ;(n = lstrlenW(fptr)) != 0; i++)
|
||||
{
|
||||
fptr += n + 1;
|
||||
if (i == index)
|
||||
return fptr;
|
||||
fptr += lstrlenW(fptr) + 1;
|
||||
}
|
||||
return (LPWSTR) FILE_star; /* FIXME */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_WMDrawItem [internal]
|
||||
*/
|
||||
LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,
|
||||
int savedlg, LPDRAWITEMSTRUCT lpdis)
|
||||
{
|
||||
WCHAR *str;
|
||||
HICON hIcon;
|
||||
COLORREF oldText = 0, oldBk = 0;
|
||||
|
||||
if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
|
||||
{
|
||||
if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE;
|
||||
SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
|
||||
(LPARAM)str);
|
||||
|
||||
if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
|
||||
{
|
||||
oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
|
||||
oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
}
|
||||
if (savedlg)
|
||||
SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
|
||||
|
||||
ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1,
|
||||
lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
|
||||
&(lpdis->rcItem), str, lstrlenW(str), NULL);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
|
||||
|
||||
if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
|
||||
{
|
||||
SetBkColor( lpdis->hDC, oldBk );
|
||||
SetTextColor( lpdis->hDC, oldText );
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
|
||||
{
|
||||
if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
|
||||
return FALSE;
|
||||
SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
|
||||
(LPARAM)str);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
|
||||
oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
}
|
||||
ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
|
||||
lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
|
||||
&(lpdis->rcItem), str, lstrlenW(str), NULL);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
SetBkColor( lpdis->hDC, oldBk );
|
||||
SetTextColor( lpdis->hDC, oldText );
|
||||
}
|
||||
DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
|
||||
HeapFree(GetProcessHeap(), 0, str);
|
||||
return TRUE;
|
||||
}
|
||||
if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
|
||||
{
|
||||
char root[] = "a:";
|
||||
if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
|
||||
return FALSE;
|
||||
SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
|
||||
(LPARAM)str);
|
||||
root[0] += str[2] - 'a';
|
||||
switch(GetDriveTypeA(root))
|
||||
{
|
||||
case DRIVE_REMOVABLE: hIcon = hFloppy; break;
|
||||
case DRIVE_CDROM: hIcon = hCDRom; break;
|
||||
case DRIVE_REMOTE: hIcon = hNet; break;
|
||||
case DRIVE_FIXED:
|
||||
default: hIcon = hHDisk; break;
|
||||
}
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
|
||||
oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
}
|
||||
ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
|
||||
lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
|
||||
&(lpdis->rcItem), str, lstrlenW(str), NULL);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
SetBkColor( lpdis->hDC, oldBk );
|
||||
SetTextColor( lpdis->hDC, oldText );
|
||||
}
|
||||
DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
|
||||
HeapFree(GetProcessHeap(), 0, str);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_UpdateResult [internal]
|
||||
* update the displayed file name (with path)
|
||||
*/
|
||||
void FD31_UpdateResult(PFD31_DATA lfs, WCHAR *tmpstr)
|
||||
{
|
||||
int lenstr2;
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
WCHAR tmpstr2[BUFFILE];
|
||||
WCHAR *bs;
|
||||
|
||||
TRACE("%s\n", debugstr_w(tmpstr));
|
||||
if(ofnW->Flags & OFN_NOVALIDATE)
|
||||
tmpstr2[0] = '\0';
|
||||
else
|
||||
GetCurrentDirectoryW(BUFFILE, tmpstr2);
|
||||
lenstr2 = strlenW(tmpstr2);
|
||||
if (lenstr2 > 3)
|
||||
tmpstr2[lenstr2++]='\\';
|
||||
lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2);
|
||||
if (ofnW->lpstrFile)
|
||||
lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
|
||||
if((bs = strrchrW(tmpstr2, '\\')) != NULL)
|
||||
ofnW->nFileOffset = bs - tmpstr2 +1;
|
||||
else
|
||||
ofnW->nFileOffset = 0;
|
||||
ofnW->nFileExtension = 0;
|
||||
while(tmpstr2[ofnW->nFileExtension] != '.' && tmpstr2[ofnW->nFileExtension] != '\0')
|
||||
ofnW->nFileExtension++;
|
||||
if (tmpstr2[ofnW->nFileExtension] == '\0')
|
||||
ofnW->nFileExtension = 0;
|
||||
else
|
||||
ofnW->nFileExtension++;
|
||||
/* update the real client structures if any */
|
||||
lfs->callbacks->UpdateResult(lfs);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_UpdateFileTitle [internal]
|
||||
* update the displayed file name (without path)
|
||||
*/
|
||||
void FD31_UpdateFileTitle(PFD31_DATA lfs)
|
||||
{
|
||||
LONG lRet;
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
if (ofnW->lpstrFileTitle != NULL)
|
||||
{
|
||||
lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0);
|
||||
SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet,
|
||||
(LPARAM)ofnW->lpstrFileTitle );
|
||||
lfs->callbacks->UpdateFileTitle(lfs);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_DirListDblClick [internal]
|
||||
*/
|
||||
static LRESULT FD31_DirListDblClick( PFD31_DATA lfs )
|
||||
{
|
||||
LONG lRet;
|
||||
HWND hWnd = lfs->hwnd;
|
||||
LPWSTR pstr;
|
||||
WCHAR tmpstr[BUFFILE];
|
||||
|
||||
/* get the raw string (with brackets) */
|
||||
lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0);
|
||||
if (lRet == LB_ERR) return TRUE;
|
||||
pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
|
||||
SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet,
|
||||
(LPARAM)pstr);
|
||||
strcpyW( tmpstr, pstr );
|
||||
HeapFree(GetProcessHeap(), 0, pstr);
|
||||
/* get the selected directory in tmpstr */
|
||||
if (tmpstr[0] == '[')
|
||||
{
|
||||
tmpstr[lstrlenW(tmpstr) - 1] = 0;
|
||||
strcpyW(tmpstr,tmpstr+1);
|
||||
}
|
||||
strcatW(tmpstr, FILE_bslash);
|
||||
|
||||
FD31_ScanDir(hWnd, tmpstr);
|
||||
/* notify the app */
|
||||
if (lfs->hook)
|
||||
{
|
||||
if (FD31_CallWindowProc(lfs, lfs->lbselchstring, lst2,
|
||||
MAKELONG(lRet,CD_LBSELCHANGE)))
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_FileListSelect [internal]
|
||||
* called when a new item is picked in the file list
|
||||
*/
|
||||
static LRESULT FD31_FileListSelect( PFD31_DATA lfs )
|
||||
{
|
||||
LONG lRet;
|
||||
HWND hWnd = lfs->hwnd;
|
||||
LPWSTR pstr;
|
||||
|
||||
lRet = lfs->callbacks->SendLbGetCurSel(lfs);
|
||||
if (lRet == LB_ERR)
|
||||
return TRUE;
|
||||
|
||||
/* set the edit control to the choosen file */
|
||||
if ((pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
|
||||
{
|
||||
SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet,
|
||||
(LPARAM)pstr);
|
||||
SetDlgItemTextW( hWnd, edt1, pstr );
|
||||
HeapFree(GetProcessHeap(), 0, pstr);
|
||||
}
|
||||
if (lfs->hook)
|
||||
{
|
||||
FD31_CallWindowProc(lfs, lfs->lbselchstring, lst1,
|
||||
MAKELONG(lRet,CD_LBSELCHANGE));
|
||||
}
|
||||
/* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD,
|
||||
CD_LBSELNOITEMS */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_TestPath [internal]
|
||||
* before accepting the file name, test if it includes wild cards
|
||||
* tries to scan the directory and returns TRUE if no error.
|
||||
*/
|
||||
static LRESULT FD31_TestPath( PFD31_DATA lfs, LPWSTR path )
|
||||
{
|
||||
HWND hWnd = lfs->hwnd;
|
||||
LPWSTR pBeginFileName, pstr2;
|
||||
WCHAR tmpstr2[BUFFILE];
|
||||
|
||||
pBeginFileName = strrchrW(path, '\\');
|
||||
if (pBeginFileName == NULL)
|
||||
pBeginFileName = strrchrW(path, ':');
|
||||
|
||||
if (strchrW(path,'*') != NULL || strchrW(path,'?') != NULL)
|
||||
{
|
||||
/* edit control contains wildcards */
|
||||
if (pBeginFileName != NULL)
|
||||
{
|
||||
lstrcpynW(tmpstr2, pBeginFileName + 1, BUFFILE);
|
||||
*(pBeginFileName + 1) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpyW(tmpstr2, path);
|
||||
if(!(lfs->ofnW.Flags & OFN_NOVALIDATE))
|
||||
*path = 0;
|
||||
}
|
||||
|
||||
TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2));
|
||||
SetDlgItemTextW( hWnd, edt1, tmpstr2 );
|
||||
FD31_ScanDir(hWnd, path);
|
||||
return (lfs->ofnW.Flags & OFN_NOVALIDATE) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* no wildcards, we might have a directory or a filename */
|
||||
/* try appending a wildcard and reading the directory */
|
||||
|
||||
pstr2 = path + lstrlenW(path);
|
||||
if (pBeginFileName == NULL || *(pBeginFileName + 1) != 0)
|
||||
strcatW(path, FILE_bslash);
|
||||
|
||||
/* if ScanDir succeeds, we have changed the directory */
|
||||
if (FD31_ScanDir(hWnd, path))
|
||||
return FALSE; /* and path is not a valid file name */
|
||||
|
||||
/* if not, this must be a filename */
|
||||
|
||||
*pstr2 = 0; /* remove the wildcard added before */
|
||||
|
||||
if (pBeginFileName != NULL)
|
||||
{
|
||||
/* strip off the pathname */
|
||||
*pBeginFileName = 0;
|
||||
SetDlgItemTextW( hWnd, edt1, pBeginFileName + 1 );
|
||||
|
||||
lstrcpynW(tmpstr2, pBeginFileName + 1, sizeof(tmpstr2)/sizeof(WCHAR) );
|
||||
/* Should we MessageBox() if this fails? */
|
||||
if (!FD31_ScanDir(hWnd, path))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
strcpyW(path, tmpstr2);
|
||||
}
|
||||
else
|
||||
SetDlgItemTextW( hWnd, edt1, path );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_Validate [internal]
|
||||
* called on: click Ok button, Enter in edit, DoubleClick in file list
|
||||
*/
|
||||
static LRESULT FD31_Validate( PFD31_DATA lfs, LPWSTR path, UINT control, INT itemIndex,
|
||||
BOOL internalUse )
|
||||
{
|
||||
LONG lRet;
|
||||
HWND hWnd = lfs->hwnd;
|
||||
OPENFILENAMEW ofnsav;
|
||||
LPOPENFILENAMEW ofnW = &lfs->ofnW;
|
||||
WCHAR filename[BUFFILE];
|
||||
|
||||
ofnsav = *ofnW; /* for later restoring */
|
||||
|
||||
/* get current file name */
|
||||
if (path)
|
||||
lstrcpynW(filename, path, sizeof(filename)/sizeof(WCHAR));
|
||||
else
|
||||
GetDlgItemTextW( hWnd, edt1, filename, sizeof(filename)/sizeof(WCHAR));
|
||||
|
||||
TRACE("got filename = %s\n", debugstr_w(filename));
|
||||
/* if we did not click in file list to get there */
|
||||
if (control != lst1)
|
||||
{
|
||||
if (!FD31_TestPath( lfs, filename) )
|
||||
return FALSE;
|
||||
}
|
||||
FD31_UpdateResult(lfs, filename);
|
||||
|
||||
if (internalUse)
|
||||
{ /* called internally after a change in a combo */
|
||||
if (lfs->hook)
|
||||
{
|
||||
FD31_CallWindowProc(lfs, lfs->lbselchstring, control,
|
||||
MAKELONG(itemIndex,CD_LBSELCHANGE));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FD31_UpdateFileTitle(lfs);
|
||||
if (lfs->hook)
|
||||
{
|
||||
lRet = (BOOL)FD31_CallWindowProc(lfs, lfs->fileokstring,
|
||||
0, lfs->lParam );
|
||||
if (lRet)
|
||||
{
|
||||
*ofnW = ofnsav; /* restore old state */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER))
|
||||
{
|
||||
if (ofnW->lpstrFile)
|
||||
{
|
||||
LPWSTR str = (LPWSTR)ofnW->lpstrFile;
|
||||
LPWSTR ptr = strrchrW(str, '\\');
|
||||
str[lstrlenW(str) + 1] = '\0';
|
||||
*ptr = 0;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_DiskChange [internal]
|
||||
* called when a new item is picked in the disk selection combo
|
||||
*/
|
||||
static LRESULT FD31_DiskChange( PFD31_DATA lfs )
|
||||
{
|
||||
LONG lRet;
|
||||
HWND hWnd = lfs->hwnd;
|
||||
LPWSTR pstr;
|
||||
WCHAR diskname[BUFFILE];
|
||||
|
||||
FD31_StripEditControl(hWnd);
|
||||
lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
|
||||
if (lRet == LB_ERR)
|
||||
return 0;
|
||||
pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
|
||||
SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet,
|
||||
(LPARAM)pstr);
|
||||
wsprintfW(diskname, FILE_specc, pstr[2]);
|
||||
HeapFree(GetProcessHeap(), 0, pstr);
|
||||
|
||||
return FD31_Validate( lfs, diskname, cmb2, lRet, TRUE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_FileTypeChange [internal]
|
||||
* called when a new item is picked in the file type combo
|
||||
*/
|
||||
static LRESULT FD31_FileTypeChange( PFD31_DATA lfs )
|
||||
{
|
||||
LONG lRet;
|
||||
WCHAR diskname[BUFFILE];
|
||||
LPWSTR pstr;
|
||||
|
||||
diskname[0] = 0;
|
||||
|
||||
lRet = SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETCURSEL, 0, 0);
|
||||
if (lRet == LB_ERR)
|
||||
return TRUE;
|
||||
pstr = (LPWSTR)SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETITEMDATA, lRet, 0);
|
||||
TRACE("Selected filter : %s\n", debugstr_w(pstr));
|
||||
SetDlgItemTextW( lfs->hwnd, edt1, pstr );
|
||||
|
||||
return FD31_Validate( lfs, NULL, cmb1, lRet, TRUE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_WMCommand [internal]
|
||||
*/
|
||||
LRESULT FD31_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
|
||||
UINT control, PFD31_DATA lfs )
|
||||
{
|
||||
switch (control)
|
||||
{
|
||||
case lst1: /* file list */
|
||||
FD31_StripEditControl(hWnd);
|
||||
if (notification == LBN_DBLCLK)
|
||||
{
|
||||
if (FD31_Validate( lfs, NULL, control, 0, FALSE ))
|
||||
EndDialog(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (notification == LBN_SELCHANGE)
|
||||
return FD31_FileListSelect( lfs );
|
||||
break;
|
||||
|
||||
case lst2: /* directory list */
|
||||
FD31_StripEditControl(hWnd);
|
||||
if (notification == LBN_DBLCLK)
|
||||
return FD31_DirListDblClick( lfs );
|
||||
break;
|
||||
|
||||
case cmb1: /* file type drop list */
|
||||
if (notification == CBN_SELCHANGE)
|
||||
return FD31_FileTypeChange( lfs );
|
||||
break;
|
||||
|
||||
case chx1:
|
||||
break;
|
||||
|
||||
case pshHelp:
|
||||
break;
|
||||
|
||||
case cmb2: /* disk dropdown combo */
|
||||
if (notification == CBN_SELCHANGE)
|
||||
return FD31_DiskChange( lfs );
|
||||
break;
|
||||
|
||||
case IDOK:
|
||||
TRACE("OK pressed\n");
|
||||
if (FD31_Validate( lfs, NULL, control, 0, FALSE ))
|
||||
EndDialog(hWnd, TRUE);
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hWnd, FALSE);
|
||||
return TRUE;
|
||||
|
||||
case IDABORT: /* can be sent by the hook procedure */
|
||||
EndDialog(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* FD31_MapStringPairsToW [internal]
|
||||
* map string pairs to Unicode
|
||||
*/
|
||||
static LPWSTR FD31_MapStringPairsToW(LPCSTR strA, UINT size)
|
||||
{
|
||||
LPCSTR s;
|
||||
LPWSTR x;
|
||||
int n, len;
|
||||
|
||||
s = strA;
|
||||
while (*s)
|
||||
s = s+strlen(s)+1;
|
||||
s++;
|
||||
n = s + 1 - strA; /* Don't forget the other \0 */
|
||||
if (n < size) n = size;
|
||||
|
||||
len = MultiByteToWideChar( CP_ACP, 0, strA, n, NULL, 0 );
|
||||
x = HeapAlloc(GetProcessHeap(),0, len * sizeof(WCHAR));
|
||||
MultiByteToWideChar( CP_ACP, 0, strA, n, x, len );
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* FD31_DupToW [internal]
|
||||
* duplicates an Ansi string to unicode, with a buffer size
|
||||
*/
|
||||
static LPWSTR FD31_DupToW(LPCSTR str, DWORD size)
|
||||
{
|
||||
LPWSTR strW = NULL;
|
||||
if (str && (size > 0))
|
||||
{
|
||||
strW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
|
||||
if (strW) MultiByteToWideChar( CP_ACP, 0, str, -1, strW, size );
|
||||
}
|
||||
return strW;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* FD31_MapOfnStructA [internal]
|
||||
* map a 32 bits Ansi structure to an Unicode one
|
||||
*/
|
||||
void FD31_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open)
|
||||
{
|
||||
LPCSTR str;
|
||||
UNICODE_STRING usBuffer;
|
||||
|
||||
ofnW->lStructSize = sizeof(OPENFILENAMEW);
|
||||
ofnW->hwndOwner = ofnA->hwndOwner;
|
||||
ofnW->hInstance = ofnA->hInstance;
|
||||
if (ofnA->lpstrFilter)
|
||||
ofnW->lpstrFilter = FD31_MapStringPairsToW(ofnA->lpstrFilter, 0);
|
||||
|
||||
if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter)))
|
||||
ofnW->lpstrCustomFilter = FD31_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter);
|
||||
ofnW->nMaxCustFilter = ofnA->nMaxCustFilter;
|
||||
ofnW->nFilterIndex = ofnA->nFilterIndex;
|
||||
ofnW->nMaxFile = ofnA->nMaxFile;
|
||||
ofnW->lpstrFile = FD31_DupToW(ofnA->lpstrFile, ofnW->nMaxFile);
|
||||
ofnW->nMaxFileTitle = ofnA->nMaxFileTitle;
|
||||
ofnW->lpstrFileTitle = FD31_DupToW(ofnA->lpstrFileTitle, ofnW->nMaxFileTitle);
|
||||
if (ofnA->lpstrInitialDir)
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpstrInitialDir);
|
||||
ofnW->lpstrInitialDir = usBuffer.Buffer;
|
||||
}
|
||||
if (ofnA->lpstrTitle)
|
||||
str = ofnA->lpstrTitle;
|
||||
else
|
||||
/* Allocates default title (FIXME : get it from resource) */
|
||||
str = open ? "Open File" : "Save as";
|
||||
RtlCreateUnicodeStringFromAsciiz (&usBuffer,str);
|
||||
ofnW->lpstrTitle = usBuffer.Buffer;
|
||||
ofnW->Flags = ofnA->Flags;
|
||||
ofnW->nFileOffset = ofnA->nFileOffset;
|
||||
ofnW->nFileExtension = ofnA->nFileExtension;
|
||||
ofnW->lpstrDefExt = FD31_DupToW(ofnA->lpstrDefExt, 3);
|
||||
if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName))
|
||||
{
|
||||
if (HIWORD(ofnA->lpTemplateName))
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpTemplateName);
|
||||
ofnW->lpTemplateName = usBuffer.Buffer;
|
||||
}
|
||||
else /* numbered resource */
|
||||
ofnW->lpTemplateName = (LPWSTR) ofnA->lpTemplateName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* FD31_FreeOfnW [internal]
|
||||
* Undo all allocations done by FD31_MapOfnStructA
|
||||
*/
|
||||
void FD31_FreeOfnW(LPOPENFILENAMEW ofnW)
|
||||
{
|
||||
if (ofnW->lpstrFilter) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrFilter);
|
||||
if (ofnW->lpstrCustomFilter) HeapFree(GetProcessHeap(), 0, ofnW->lpstrCustomFilter);
|
||||
if (ofnW->lpstrFile) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFile);
|
||||
if (ofnW->lpstrFileTitle) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle);
|
||||
if (ofnW->lpstrInitialDir) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir);
|
||||
if (ofnW->lpstrTitle) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle);
|
||||
if ((ofnW->lpTemplateName) && (HIWORD(ofnW->lpTemplateName)))
|
||||
HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* FD31_DestroyPrivate [internal]
|
||||
* destroys the private object
|
||||
*/
|
||||
void FD31_DestroyPrivate(PFD31_DATA lfs)
|
||||
{
|
||||
HWND hwnd;
|
||||
if (!lfs) return;
|
||||
hwnd = lfs->hwnd;
|
||||
TRACE("destroying private allocation %p\n", lfs);
|
||||
lfs->callbacks->Destroy(lfs);
|
||||
HeapFree(GetProcessHeap(), 0, lfs);
|
||||
RemovePropA(hwnd, FD31_OFN_PROP);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* FD31_AllocPrivate [internal]
|
||||
* allocate a private object to hold 32 bits Unicode
|
||||
* structure that will be used throughtout the calls, while
|
||||
* keeping available the original structures and a few variables
|
||||
* On entry : type = dialog procedure type (16,32A,32W)
|
||||
* dlgType = dialog type (open or save)
|
||||
*/
|
||||
PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType,
|
||||
PFD31_CALLBACKS callbacks, DWORD data)
|
||||
{
|
||||
PFD31_DATA lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FD31_DATA));
|
||||
|
||||
TRACE("alloc private buf %p\n", lfs);
|
||||
if (!lfs) return NULL;
|
||||
lfs->hook = FALSE;
|
||||
lfs->lParam = lParam;
|
||||
lfs->open = (dlgType == OPEN_DIALOG);
|
||||
lfs->callbacks = callbacks;
|
||||
if (! lfs->callbacks->Init(lParam, lfs, data))
|
||||
{
|
||||
FD31_DestroyPrivate(lfs);
|
||||
return NULL;
|
||||
}
|
||||
lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRINGA);
|
||||
lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRINGA);
|
||||
|
||||
return lfs;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FD31_WMInitDialog [internal]
|
||||
*/
|
||||
|
||||
LONG FD31_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int i, n;
|
||||
WCHAR tmpstr[BUFFILE];
|
||||
LPWSTR pstr, old_pstr;
|
||||
LPOPENFILENAMEW ofn;
|
||||
PFD31_DATA lfs = (PFD31_DATA) lParam;
|
||||
|
||||
if (!lfs) return FALSE;
|
||||
SetPropA(hWnd, FD31_OFN_PROP, (HANDLE)lfs);
|
||||
lfs->hwnd = hWnd;
|
||||
ofn = &lfs->ofnW;
|
||||
|
||||
TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir));
|
||||
|
||||
SetWindowTextW( hWnd, ofn->lpstrTitle );
|
||||
/* read custom filter information */
|
||||
if (ofn->lpstrCustomFilter)
|
||||
{
|
||||
pstr = ofn->lpstrCustomFilter;
|
||||
n = 0;
|
||||
TRACE("lpstrCustomFilter = %p\n", pstr);
|
||||
while(*pstr)
|
||||
{
|
||||
old_pstr = pstr;
|
||||
i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
|
||||
(LPARAM)(ofn->lpstrCustomFilter) + n );
|
||||
n += lstrlenW(pstr) + 1;
|
||||
pstr += lstrlenW(pstr) + 1;
|
||||
TRACE("add str=%s associated to %s\n",
|
||||
debugstr_w(old_pstr), debugstr_w(pstr));
|
||||
SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
|
||||
n += lstrlenW(pstr) + 1;
|
||||
pstr += lstrlenW(pstr) + 1;
|
||||
}
|
||||
}
|
||||
/* read filter information */
|
||||
if (ofn->lpstrFilter) {
|
||||
pstr = (LPWSTR) ofn->lpstrFilter;
|
||||
n = 0;
|
||||
while(*pstr) {
|
||||
old_pstr = pstr;
|
||||
i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
|
||||
(LPARAM)(ofn->lpstrFilter + n) );
|
||||
n += lstrlenW(pstr) + 1;
|
||||
pstr += lstrlenW(pstr) + 1;
|
||||
TRACE("add str=%s associated to %s\n",
|
||||
debugstr_w(old_pstr), debugstr_w(pstr));
|
||||
SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
|
||||
n += lstrlenW(pstr) + 1;
|
||||
pstr += lstrlenW(pstr) + 1;
|
||||
}
|
||||
}
|
||||
/* set default filter */
|
||||
if (ofn->nFilterIndex == 0 && ofn->lpstrCustomFilter == NULL)
|
||||
ofn->nFilterIndex = 1;
|
||||
SendDlgItemMessageW(hWnd, cmb1, CB_SETCURSEL, ofn->nFilterIndex - 1, 0);
|
||||
lstrcpynW(tmpstr, FD31_GetFileType(ofn->lpstrCustomFilter,
|
||||
(LPWSTR)ofn->lpstrFilter, ofn->nFilterIndex - 1),BUFFILE);
|
||||
TRACE("nFilterIndex = %ld, SetText of edt1 to %s\n",
|
||||
ofn->nFilterIndex, debugstr_w(tmpstr));
|
||||
SetDlgItemTextW( hWnd, edt1, tmpstr );
|
||||
/* get drive list */
|
||||
*tmpstr = 0;
|
||||
DlgDirListComboBoxW(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
|
||||
/* read initial directory */
|
||||
/* FIXME: Note that this is now very version-specific (See MSDN description of
|
||||
* the OPENFILENAME structure). For example under 2000/XP any path in the
|
||||
* lpstrFile overrides the lpstrInitialDir, but not under 95/98/ME
|
||||
*/
|
||||
if (ofn->lpstrInitialDir != NULL)
|
||||
{
|
||||
int len;
|
||||
lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511);
|
||||
len = lstrlenW(tmpstr);
|
||||
if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
|
||||
tmpstr[len]='\\';
|
||||
tmpstr[len+1]='\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
*tmpstr = 0;
|
||||
if (!FD31_ScanDir(hWnd, tmpstr)) {
|
||||
*tmpstr = 0;
|
||||
if (!FD31_ScanDir(hWnd, tmpstr))
|
||||
WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr));
|
||||
}
|
||||
/* select current drive in combo 2, omit missing drives */
|
||||
{
|
||||
char dir[MAX_PATH];
|
||||
char str[4] = "a:\\";
|
||||
GetCurrentDirectoryA( sizeof(dir), dir );
|
||||
for(i = 0, n = -1; i < 26; i++)
|
||||
{
|
||||
str[0] = 'a' + i;
|
||||
if (GetDriveTypeA(str) > DRIVE_NO_ROOT_DIR) n++;
|
||||
if (toupper(str[0]) == toupper(dir[0])) break;
|
||||
}
|
||||
}
|
||||
SendDlgItemMessageW(hWnd, cmb2, CB_SETCURSEL, n, 0);
|
||||
if (!(ofn->Flags & OFN_SHOWHELP))
|
||||
ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
|
||||
if (ofn->Flags & OFN_HIDEREADONLY)
|
||||
ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
|
||||
if (lfs->hook)
|
||||
return (BOOL) FD31_CallWindowProc(lfs, WM_INITDIALOG, wParam, lfs->lParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int FD31_GetFldrHeight(void)
|
||||
{
|
||||
return fldrHeight;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Win3.1 style File Dialog interface (32 bit)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _WINE_DLL_FILEDLG31_H
|
||||
#define _WINE_DLL_FILEDLG31_H
|
||||
|
||||
#define FD31_OFN_PROP "FILEDLG_OFN"
|
||||
|
||||
/* Forward declare */
|
||||
typedef struct tagFD31_DATA *PFD31_DATA;
|
||||
|
||||
typedef struct tagFD31_CALLBACKS
|
||||
{
|
||||
BOOL (CALLBACK *Init)(LPARAM lParam, PFD31_DATA lfs, DWORD data);
|
||||
BOOL (CALLBACK *CWP)(PFD31_DATA lfs, UINT wMsg, WPARAM wParam,
|
||||
LPARAM lParam); /* CWP instead of CallWindowProc to avoid macro expansion */
|
||||
void (CALLBACK *UpdateResult)(PFD31_DATA lfs);
|
||||
void (CALLBACK *UpdateFileTitle)(PFD31_DATA lfs);
|
||||
LRESULT (CALLBACK *SendLbGetCurSel)(PFD31_DATA lfs);
|
||||
void (CALLBACK *Destroy)(PFD31_DATA lfs);
|
||||
} FD31_CALLBACKS, *PFD31_CALLBACKS;
|
||||
|
||||
typedef struct tagFD31_DATA
|
||||
{
|
||||
HWND hwnd; /* file dialog window handle */
|
||||
BOOL hook; /* TRUE if the dialog is hooked */
|
||||
UINT lbselchstring; /* registered message id */
|
||||
UINT fileokstring; /* registered message id */
|
||||
LPARAM lParam; /* save original lparam */
|
||||
LPCVOID template; /* template for 32 bits resource */
|
||||
BOOL open; /* TRUE if open dialog, FALSE if save dialog */
|
||||
OPENFILENAMEW ofnW; /* copy of original structure or work struct */
|
||||
LPVOID private1632; /* 16/32 bit caller private data */
|
||||
PFD31_CALLBACKS callbacks; /* callbacks to handle 16/32 bit differences */
|
||||
} FD31_DATA;
|
||||
|
||||
extern BOOL FD31_Init(void);
|
||||
extern PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType,
|
||||
PFD31_CALLBACKS callbacks, DWORD data);
|
||||
extern void FD31_DestroyPrivate(PFD31_DATA lfs);
|
||||
extern void FD31_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open);
|
||||
extern void FD31_FreeOfnW(LPOPENFILENAMEW ofnW);
|
||||
extern BOOL FD31_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
extern LONG FD31_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
extern LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,
|
||||
int savedlg, LPDRAWITEMSTRUCT lpdis);
|
||||
extern LRESULT FD31_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
|
||||
UINT control, PFD31_DATA lfs);
|
||||
extern int FD31_GetFldrHeight(void);
|
||||
|
||||
#endif /* _WINE_DLL_FILEDLG31_H */
|
Loading…
Reference in New Issue