TSaveDialog는 윈도우 환경에서 파일 저장 대화상자를 구현할 때 유용하게 사용되는 컴포넌트입니다. 하지만 Windows XP와 Vista에서 파일 타입을 변경할 때 파일명 확장자가 자동으로 변경되지 않는 문제를 겪을 수 있습니다. 이 글에서는 이러한 문제를 해결하기 위한 구체적인 방법을 제시합니다.
TSaveDialog 소개
TSaveDialog는 파일을 저장할 때 파일 형식을 선택할 수 있도록 도와주는 다이얼로그입니다. 사용자는 다양한 파일 형식 중 하나를 선택하여 저장할 수 있으며, 이는 개발자가 TSaveDialog의 Filter 속성을 통해 설정할 수 있습니다. 그러나 Windows XP와 Vista에서 TSaveDialog를 사용할 때 파일 형식을 변경해도 파일명 확장자가 자동으로 변경되지 않는 문제를 겪을 수 있습니다.
문제 발생 배경
Windows 7의 동작 방식
Windows 7에서는 TSaveDialog에서 파일 형식을 변경할 경우, 기본적으로 지정된 파일명의 확장자가 자동으로 변경된 파일 형식의 확장자로 바뀝니다. 예를 들어, 기본 파일명이 "document.txt"이고 파일 형식을 ".xls"로 변경하면 파일명이 "document.xls"로 자동으로 변경됩니다.
Windows XP와 Vista의 문제점
하지만 Windows Vista와 Windows XP에서는 이와 같은 자동 변경 기능이 작동하지 않습니다. 사용자가 파일 형식을 변경해도 파일명 확장자는 그대로 남아 있으며, 이는 사용자에게 불편을 초래할 수 있습니다.
해결 방법
VISTA에서의 해결책
Windows Vista에서는 TSaveDialog.OnTypeChange 이벤트를 활용하여 파일 형식을 변경할 때 확장자를 강제로 지정할 수 있습니다. 이를 위해 필터 인덱스에 따라 확장자를 설정하고, TSaveDialog.FileName 속성에 강제로 파일명을 지정하면 됩니다.
procedure TfrmOrderEdit.dlgSaveTocFileTypeChange(Sender: TObject);
var
ext : string;
begin
case dlgSaveTocFile.FilterIndex of
1 : ext := '.xls';
2 : ext := '.txt';
end;
dlgSaveTocFile.FileName := ChangeFileExt(dlgSaveTocFile.FileName, ext);
end;
XP에서의 해결책
XP에서는 위와 같은 방법으로도 파일명 확장자가 자동으로 변경되지 않는 문제가 여전히 남아 있습니다. 따라서 다음과 같은 방법을 통해 문제를 해결할 수 있습니다.
필요한 함수 정의
먼저 자식 컨트롤에서 특정 인덱스의 컨트롤 핸들을 찾는 함수를 정의합니다.
function FindChildWindow(winHandle: HWND; nIdx: Integer): HWND; overload;
var
count: Integer;
begin
result := 0;
winHandle := FindWindowEx(winHandle, 0, nil, nil);
count := 0;
while winHandle <> 0 do
begin
inc(count);
if nIdx = count then
begin
result := winHandle;
break;
end;
winHandle := GetNextWindow(winHandle, GW_HWNDNEXT);
end;
end;
다음으로 EDIT 컨트롤의 TEXT를 설정하는 함수를 정의합니다.
procedure SendCharToEditControl(hd: THandle; AMsg: string);
begin
SendMessage(hd, WM_SETTEXT, 0, Integer(PChar(AMsg)));
end;
OnTypeChange 이벤트 핸들러 구현
TSaveDialog.OnTypeChange 이벤트 핸들러에서 파일 타입에 따른 확장자를 획득한 후, TSaveDialog 창 내의 파일명 컨트롤을 찾아 직접 변경할 파일명을 지정하는 방법을 사용합니다.
procedure TfrmOrderEdit.dlgSaveTocFileTypeChange(Sender: TObject);
var
ext: string;
fname: string;
hd: HWND;
begin
case dlgSaveTocFile.FilterIndex of
1: ext := '.xls';
2: ext := '.txt';
end;
fname := ExtractFileNameWithoutExt(dlgSaveTocFile.FileName) + ext;
hd := FindChildWindow(GetParent(dlgSaveTocFile.Handle), 9); // FIND COMBOBOXEX32
hd := FindChildWindow(hd, 1); // FIND COMBOBOX
hd := FindChildWindow(hd, 1); // FIND EDIT
SendCharToEditControl(hd, fname);
end;
주요 함수 설명
- FindChildWindow: 주어진 윈도우 핸들에서 특정 인덱스의 자식 컨트롤 핸들을 찾습니다.
- SendCharToEditControl: 주어진 핸들의 EDIT 컨트롤에 문자열을 설정합니다.
- dlgSaveTocFileTypeChange: TSaveDialog.OnTypeChange 이벤트 핸들러로, 파일 타입에 따라 확장자를 변경하고 파일명 컨트롤을 업데이트합니다.
결론
위의 방법을 통해 Windows XP와 Vista에서 TSaveDialog를 사용할 때 파일 형식을 변경해도 파일명 확장자가 자동으로 변경되지 않는 문제를 해결할 수 있습니다. 이 방법은 필터 인덱스를 기반으로 파일 확장자를 설정하고, TSaveDialog 창 내의 파일명 컨트롤을 직접 조작하여 파일명을 업데이트합니다. 이를 통해 사용자에게 보다 편리한 파일 저장 경험을 제공할 수 있습니다.
'delphi' 카테고리의 다른 글
Delphi XE를 이용한 ISAPI DLL 프로젝트 생성 및 배포 방법 (0) | 2024.08.07 |
---|---|
REST(Representational State Transfer) 아키텍처에 대한 심층 분석 (0) | 2024.08.07 |
델파이의 콘트롤들을 이용한 애니메이션 효과 적용 방법 (0) | 2024.08.06 |
델파이에서 리소스(메모리/GDI) 누수에 대해 Denomo 모듈을 사용해 보자 (0) | 2024.08.06 |
JPEG/GIF/BMP/PNG/PCX 이미지 정보 얻기 (0) | 2024.08.02 |