안녕하세요. 아래 최용일님의 즐겨찾기 강의 소스고요. 이걸 사용해서
즐겨찾기에 자동으로 메뉴가 만들어 지는 것만 만들려고 하는데요..
바탕화면이나 다른 건 안되도 됩니다.
그런데... 안되네요??
왜 안되는지 모르겠습니다.
궁금한 점은 아래 소스에서
Params.TargetFilename := 'C:Program FilesStarcraftstarcraft.exe';
경로를 위와 같이 주는데..
c:\program files\Starcraft\Starcraft.exe이렇게 주는 것이 아닌가요??
왜\가 없는지.. 그게 맞는지.. 궁금합니다.
고수님들의 도움 부탁드립니다.
===============================
최용일
Subject
[강좌] 바로가기 만들기
안녕하세요. 최용일입니다.
쉽게 설명하겠습니다. 프로그램상에 문제가 있다면 멜 주세요...
사실 이러한 바로가기와 같은 쉘 확장 프로그래밍은 COM에 대한 이해가
없인 사용하기가 힘든 부분이 많습니다. 컨텍스트 메뉴나 바로가기
같은 쉘 확장이 바로 COM으로 만들어졌기 때문이죠...
COM에서 중요한것이 바로 인터페이스(Interface)입니다. 쉽게 말하면 class와
비슷하다고 생각하시면 됩니다. 자세한 것은 COM에 관련된 책자를 찾아보세요.
아래서 사용한 IUnknown, IShellLink, IPersistFile과 같은 것들이 인터페이스죠.
사용법은 클래스와 같습니다. 몇몇 쉘 확장 COM 프로그램에선 인터페이스를
생성하는 것이 아니라 얻어서 사용합니다.. 많은 기본적인의 쉘 확장은 이미
MS사에서 만들어 놓았습니다. 우리는 그것을 가져다 쓰면 됩니다....
# 모든 클래스의 선조가 TObject인것처럼 모든 인터페이스의 선조는 IUnknown입니다.
바로가기를 만드는 IShellLink 인터페이스 객체를 얻는 방법에는 두가지가 있습니다.
하나는 COM을 초기화(CoInitialize)한 후 CoCreateInstance를 이용하여 얻는방법과
또 하나는 CreateComObject를 사용하여 IUnknown인터페이스 객체를 얻은후 as연산자
를 사용하여 IUnknown에서 추출하는 방법이 있습니다. 어느 방법을 사용하나 똑같은
결과를 얻습니만 두번째 방법이 더 간결합니다.
IShellLink인터페이스가 하는 일은 바로가기에 대한 여러가지 값들을 설정하는
것입니다. 그리고 IPersistFile은 생성된 바로가기를 저장하는데 쓰입니다.
사실 바로가기를 만드는데 필요한 인자들이 너무 많기 때문에 레코드를 이용하여
인자를 넣도록 하겠습니다. 다음과 같은 레코드를 쓰겠습니다.
TShellLinkParams = record
// 프로그램의 파라매터를 설정할때 사용합니다.
Arguments: string;
// 이 바로가기에 대한 설명입니다.
// 탐색기에서 파일에 대한 등록정보를 보실때 아이콘 옆에 써지는 글입니다.
Description: string;
// 이 바로가기에 대한 핫키입니다.
// 탐색기 등록정보에서 "바로 가는 키"라고 써진 부분에 나타납니다.
// 핫키는 Ctrl, Alt, Shift의 조합으로된 가상키값을 써주시면 됩니다.
// 핫키가 필요없다면 그냥 0을 넣어주세요.
HotKey: Word;
// 이 바로가기가 보여질때 나타나는 아이콘이 들어 있는 파일을 나타냅니다.
// 풀 패스네임을 적어주시면 되고 없다면 그냥 ''를 넣어주세요 그럼 기본적
// 으로 Unknown File의 확장자가 보일테니까요..
IconLocation: string;
// 아이콘이 들어 있는 파일에서의 아이콘의 위치입니다. 첫번째 아이콘은 0
IconIndex: Integer;
// 이건 바로가기가 나타날때 어떻게 보여지는가를 나타냅니다.
// 탐색기 등록정보창을 보시면 "실행"이라는 부분을 바로 여기서 설정합니다.
// 이것은 세가지 값을 중의 하나입니다.
// SW_SHOWNORMAL - 윈도가 일반적인 형태로 실행됩니다. (기본창)
// SW_SHOWMAXIMIZED - 윈도가 최대화되어 실행됩니다. (최대화)
// SW_SHOWMINIMIZED - 윈도가 최소화되어 실행됩니다. (최소화)
ShowCommand: Integer;
// 이건 대상파일의 이름, 즉 이 바로가기가 눌렸을 때 실행되는 파일의 이름
// 입니다. 풀패스로 적어주세요.
// 탐색기 등록정보창에서 "대상"이라고 써진 부분에 나타납니다.
TargetFilename: string;
// 이건 바로가기가 실행된 후의 디렉토리을 설정합니다. 특별한 경우가
// 아니면 ''을 넣어주세요. 그럼 작업디렉토리가 대상 파일의 경로로
// 설정됩니다. 탐색기 등록정보의 "시작위치"에 나타납니다.
WorkingDir: string;
// 여기엔 바로가기가 생성될 경로명을 써주세요..
LinkPath: string;
// 만일 일반적인 디렉토리에서가 아니라 "바탕화면"이나 "시작메뉴"와 같은
// 특별한 폴더내에 생성되게 할려면 이걸 True로 설정하고 아래의 SpecialFolder에
// 특수 폴더명을 써주시면 됩니다.
UseSpecialFolder: LongBool;
// 이 값은 UseSpecialFolder가 True일 때만 사용합니다. 특수 폴더에
// 바로가기를 생성할 때 사용합니다. 특수 폴더명에 대한 값들은 ShlObj유닛에
// 선언되어 있습니다.
// CSIDL_DESKTOP - 바탕화면
// CSIDL_PROGRAMS - 시작메뉴의 프로그램메뉴
// CSIDL_PERSONAL - 내 문서
// CSIDL_FAVORITES - 즐겨찾기
// CSIDL_STARTUP - 시작메뉴프로그램시작프로그램
// CSIDL_RECENT - 최근 사용한 문서?? 맞나?? 제 컴에선 삭제를 해버려서...
// CSIDL_STARTMENU - 시작메뉴
// ...... - ShlObj 유닛을 참조하세요.
SpecialFolder: Word;
end;
******************************
그럼 유닛파일을 만들겠습니다.
******************************
unit ShlLink;
interface
uses Windows, SysUtils, ShlObj, ActiveX, ShellAPI, ComObj;
type
TShellLinkParams = record
Arguments: string;
Description: string;
HotKey: Word;
IconLocation: string;
IconIndex: Integer;
ShowCommand: Integer;
TargetFileName: string;
WorkingDir: string;
LinkPath: string;
UseSpecialFolder: LongBool;
SpecialFolder: Word;
end;
// 이 두개의 함수는 똑같은 일을 합니다. 다만 IShellLink 인터페이스를
// 얻는 방법이 다를 뿐입니다. 제대로 생성이 되었다면 True를 돌려줍니다.
// 첫번째 파라매터인 Handle은 특수 폴더에 바로가기를 생성할 때 특수
// 폴더의 패스를 얻을 때 사용합니다.
function CreateShellLink(Handle: HWND; var Params: TShellLinkParams): Boolean;
function CreateShellLink2(Handle: HWND; var Params: TShellLinkParams): Boolean;
implementation
function CreateShellLink(Handle: HWND; var Params: TShellLinkParams): Boolean;
var
pUnknown: IUnknown;
pShellLink: IShellLink;
pPersistFile: IPersistFile;
InitErrorCode, SHErrorCode: HRESULT;
pPidl: PItemIDList;
LinkFileName: string;
FileExt: string;
wcLinkFileName: array[0..Max_Path] of WideChar;
SpecialFolderPath: array[0..Max_Path] of Char;
begin
Result := False;
// CreateComObject는 ComObject를 초기화 하고 해당 CLSID에 대한 COM객체를
// 반환합니다.
pUnknown := CreateComObject(CLSID_ShellLink);
// IUnknown인터페이스에서 IShellLink와 IPersistFile인터페이스를 얻습니다.
// IShellLink와 IPersistFile인터페이스는 IUnknown에서 파생되었습니다.
pShellLink := pUnknown as IShellLink;
pPersistFile := pUnknown as IPersistFile;
// IShellLink인터페이스를 이용하여 여러가지 값들을 셋팅합니다.
// 메소드 이름들이 명시적이라 설명은 안하겠습니다.
// 모두 C++로 짠 COM이라서 string타입은 거의 사용되지 않습니다.
// 대부분 PChar형을 많이 쓰죠. 모두 PChar타입으로 형변환을 해주었습니다.
// TShellLinkParams.Argument 참조
pShellLink.SetArguments(PChar(Params.Arguments));
// TShellLinkParams.Description 참조
pShellLink.SetDescription(PChar(Params.Description));
// TShellLinkParams.HotKey 참조
pShellLink.SetHotkey(Params.HotKey);
// TShellLinkParams.IconLocation 참조
pShellLink.SetIconLocation(PChar(Params.IconLocation), Params.IconIndex);
// TShellLinkParams.ShowCommand 참조
pShellLink.SetShowCmd(Params.ShowCommand);
// TShellLinkParams.TargetFilename 참조
pShellLink.SetPath(PChar(Params.TargetFileName));
// 작업디렉토리를 설정하지 않았다면 대상파일의 디렉토리를 작업
// 디렉토리로 사용합니다.
if Params.WorkingDir = '' then
Params.WorkingDir := ExtractFilePath(Params.TargetFileName);
pShellLink.SetWorkingDirectory(PChar(Params.WorkingDir));
// 바로가기 파일 이름은 대상파일의 이름에 확장자만 바로가기
// 확장자(.lnk)를
c:\program files\Starcraft\Starcraft.exe 이렇게 \를 붙이는게 맞습니다.
예제를 쓸 때는 분명히 붙여서 썼었는데... ㅠㅠ...
^^ 항상 즐코하세요...