2007年5月3日木曜日

COMによるショートカットの作成

ヘルプにも載っているCOMによるショートカットの作成。// COMの練習。似非ハンガリアン記法も導入してみた
//    fn = File_Name, dn = Directory_Name
//    id = object_ID, s  = String
//    c  = Com_object
// 参考 ・http://yokohama.cool.ne.jp/chokuto/urawaza/com/shell.html
//      ・http://ameblo.jp/argv/entry-10031517216.html
#include "hspext.as"

// シェルリンクオブジェクトのクラスID
    #define  CLSID_ShellLink   "{00021401-0000-0000-C000-000000000046}"
// IShellLinkインターフェースのインターフェースID
    #define  IID_IShellLinkA   "{000214EE-0000-0000-C000-000000000046}"
// IShellLinkインターフェースの持つSetPathメソッド
    #usecom  IShellLinkA IID_IShellLinkA
    #comfunc IShellLink_SetPath 20 str

// IPersistFileインターフェースのインターフェースID
    #define  IID_IPersistFile  "{0000010b-0000-0000-C000-000000000046}"
// IPersistFile のインターフェースの持つSaveメソッド
    #usecom  IPersistFile IID_IPersistFile
    #comfunc IPersistFile_Save 6 wstr, int

// 変数の初期化
    dnShortcut = DIR_DESKTOP
    fnShortcut = "shortcut.lnk"
    fnTarget   = dir_exe + "\\hsed3.exe"
    sTmp       = ""
    newcom cSLink, CLSID_ShellLink

// 画面の初期化
    gosub *makeScreen

    stop

*makeScreen
    screen 0380200
    objmode 11
    syscolor 5 : boxf
    syscolor 8 : sysfont 17

    pos  30,  30 : mes "対象ファイル"
    pos  30,  70 : mes "保存先フォルダ"
    pos  30110 : mes "ショートカットの名前"

    objsize 160
    pos 130,  27 : input fnTarget   : idInputTargetName    = stat
    pos 130,  67 : input dnShortcut : idInputDirectoryName = stat
    pos 130107 : input fnShortcut : idInputShortcutName  = stat

    objsize 60
    pos 290,  27 : button gosub "選択"*selectTarget
    pos 290,  67 : button gosub "選択"*selectDirectory
    pos 290107 : button gosub "選択"*selectShortcut

    objsize 32040
    pos  30150 : button gosub "ショートカット作成"*makeShortcut
    return

*makeShortcut
    // パスの確認
    exist fnTarget
    if strsize < 0 {
        dialog "対象ファイルのパスが正しくありません。"1
        return
    }

    // 保存先フォルダの存在を確認
    dirlist sTmp, dnShortcut, 5
    if stat == 0 {
        dialog "保存先フォルダのパスが正しくありません。"1
        return
    }

    // 上書き確認
    exist dnShortcut + "\\" + fnShortcut
    if strsize >= 0  {
        dialog "既にファイルが存在します。上書きしますか?"2
        if stat == 7 : return
    }

    // ショートカット作成を実行
    IShellLink_SetPath cSLink, fnTarget
    IPersistFile_Save  cSLink, dnShortcut + "\\" + fnShortcut, 1
    // 上2行は以下とほぼ同値 (hspext)
    ; chdir dnShortcut
    ; fxlink getpath(fnShortcut, 1), fnTarget

    dialog "ショートカットを作成しました。"
    return

*selectDirectory
    selfolder sTmp, ""
    if stat == 0 {
        dnShortcut = sTmp
        objprm idInputDirectoryName, sTmp
    }
    return

*selectTarget
    dialog "*"16
    if stat == 1 {
        fnTarget = refstr
        objprm idInputTargetName, fnTarget
    }
    return

*selectShortcut
    dialog "lnk"17
    if stat == 1 {
        fnShortcut = getpath(refstr1) + ".lnk"
        objprm idInputShortcutName, fnShortcut
    }
    return