COMを利用した、日付を扱うモジュールです。
指定した日の曜日を算出する関数と、指定した2つの日の差(日数)を算出する関数を含んでいます。
日数算出は「あと何日あるか」を算出するので、このサンプルプログラムのように「全部で何日か」を計算する場合は1を足す必要があります。/*
日付を扱うライブラリになりそうなもの。
※ 注意!パラメータチェック&エラーチェック処理未実装!
参考:http://tsu.sakura.ne.jp/article/note/eid512.html
*/
#module
// ミリ秒を日に変換
#define ctype cnvMsec2Day(%1) int((%1)/86400000) // 86400000 = 1000*60*60*24
// javascript数式の計算
#defcfunc jsEval str jsExp
if vartype(mssc) != vartype("comobj") {
newcom mssc, "MSScriptControl.ScriptControl"
comres result
mssc("Language") = "JScript"
}
mssc -> "Eval" jsExp
return result
// 曜日を返す(0~6)
#defcfunc getDayOf int y, int m, int d
return int(jsEval("(new Date(" + y + "," + (m - 1) + "," + d + ")).getDay();"))
// 時間差を日数で返す
#defcfunc getSub int y1, int m1, int d1, int y2, int m2, int d2
return cnvMsec2Day(jsEval("Date.UTC(" + y2 + "," + (m2 - 1) + "," + d2 + ") - Date.UTC(" + y1 + "," + (m1 - 1) + "," + d1 + ");"))
#global
// モジュールここまで
day = "日", "月", "火", "水", "木", "金", "土"
mes "今年は" + (1 + getSub( gettime(0), 1, 1, gettime(0), 12, 31 )) + "日間です"
mes "今日は" + day( getDayOf( gettime(0), gettime(1), gettime(3) ) ) + "曜日です"
stop
2008年3月1日土曜日
日数計算・曜日計算
2008年1月28日月曜日
サイトのサムネイルを表示する
サイトのサムネイルを作成・表示するAPI「ThumbnailAPI」を利用します。
ネットの接続などはスクリプトから明示的には行っていません。imgload命令の内部で使用しているCOMが自動で行ってくれているようです。#include "mod_img.as"
imgload "http://img.simpleapi.net/small/http://www.forest.impress.co.jp/"
stop
2008年1月24日木曜日
複数行文字列の行数を取得する(2)
FUJIさんのご指摘を受けて、HSP標準のnotemaxとほぼ同等の動作をするモジュール。
参考:複数行文字列の行数を取得する// 行数取得モジュール
// 変数の型チェックは行っていないので注意
#module
// instr()を利用した行数の取得
#defcfunc get_lines_num1 var p1
result = 0
repeat strlen(p1)
result++
ins = instr(p1, cnt, "\n")
if ins == -1 : break
continue cnt + ins + 2
loop
return result
// 正規表現を利用した行数の取得
#defcfunc get_lines_num2 var p1
if vartype(com_regexp) != vartype("comobj") {
// comオブジェクト型変数の初期化
newcom com_regexp, "VBScript.RegExp"
comres com_result
com_regexp("Pattern") = "\\r\\n"
com_regexp("Global") = 1
}
com_regexp->"Execute" p1
result = com_result("Count") + 1 // 行数 = 改行の個数 + 1
s = strmid(p1, -1, 2)
if s == "\n" | s == "" : result-- // 最後が空行ならその行をカウントしない
return result
// notemaxを利用した行数の取得
#defcfunc get_lines_num3 var p1
notesel p1
result = notemax
noteunsel
return result
#global
sdim s, 32, 3
s(0) = "Hot\nSoup\nProcessor"
s(1) = "sample\nstrings\n"
s(2) = ""
foreach s
mes get_lines_num1(s(cnt))
mes get_lines_num2(s(cnt))
mes get_lines_num3(s(cnt))
mes "***"
loop
stop
2008年1月23日水曜日
複数行文字列の行数を取得する
notemaxのように複数行文字列の行数を取得します。
正規表現版はパターンを"(\\r\\n)+"に変更することで、空行を無視するようにもできます。#module
// instr()を利用した行数の取得
#defcfunc get_lines_num var p1
result = 0
repeat
result++
ins = instr(p1, cnt, "\n")
if ins == -1 : break
continue cnt + ins + 2
loop
return result
// 正規表現を利用した行数の取得
#defcfunc get_lines_num2 var p1
if vartype(com_regexp) != vartype("comobj") {
// comオブジェクト型変数の初期化
newcom com_regexp, "VBScript.RegExp"
comres com_result
com_regexp("Pattern") = "\\r\\n"
com_regexp("Global") = 1
}
com_regexp->"Execute" p1
return com_result("Count") + 1 // 行数 = 改行の個数 + 1
#global
s = "Hot\nSoup\nProcessor\n\n"
mes get_lines_num(s)
mes get_lines_num2(s)
stop
2008年1月13日日曜日
数式の分解
正規表現を使って数式を分解し、文字列型配列変数に代入します。
日本語が使えないのが難点です。
関連:インタプリンタ電卓もどき#runtime "hsp3cl"
#module
// 正規表現を利用した数式の分解
// 英数字およびアンダースコア・半角丸かっこと各種演算子のみ使用可能(日本語は無視)
#deffunc split_calc array result, str exp
newcom oReg, "VBScript.RegExp"
comres oMatches
oReg("Global") = 1
oReg("Pattern") = "[0-9\\.]+|\\+|-|\\*|/|%|=|\\w*\\(|\\)|\\w+"
oReg -> "Execute" exp
sdim result, 16, oMatches("Count")
bracket_l = 0 : bracket_r = 0
repeat oMatches("Count")
oMatch = oMatches("Item", cnt)
result(cnt) = oMatch("Value")
s = strmid(result(cnt), -1, 1)
if s == "(" : bracket_l++ : else : if s == ")" : bracket_r++
loop
return bracket_l != bracket_r
#global
exp = "s(r) = r * r * 3.14"
mes exp + "\n"
// 数式を分解
split_calc result, exp
if stat : mes "括弧の数が不正です。"
// 結果の表示
foreach result
mes result(cnt)
loop
stop
2008年1月7日月曜日
APIを利用して英語を日本語に翻訳するモジュール
英語を日本語に翻訳します。
ネットに接続するため、少し時間がかかります。// 英語->日本語変換サンプル
// 翻訳APIを使用
// http://muumoo.jp/news/2007/05/09/0translationapi.html
// 参考:mod_rss.as
#module mod_translate
#deffunc rss2load_init@mod_translate
newcom oDom,"Microsoft.XMLDOM"
oDom("async") = "FALSE"
comres elm_desc
return
#deffunc rss2load@mod_translate array desc, str url, int p_max
oDom->"load" url
oRoot = oDom("documentElement")
if varuse(oRoot) == 0 : return 1
if oRoot("tagName") != "rss" : return 2
maxnum = p_max
if maxnum <= 0 : maxnum = 5
oDom->"getElementsByTagName" "description"
max = limit(elm_desc("length"), 1, maxnum)
sdim desc, 64, max
repeat max
node = elm_desc("item", cnt)
node2 = node("firstChild")
desc(cnt) = node2("nodeValue")
loop
return 0
#deffunc rss2load_clean onexit
if vartype(oRoot) == vartype("comobj") {
delcom node : delcom node2 : delcom oRoot
}
delcom elm_desc : delcom oDom
return
// 英文を和訳します。変換に成功するとstatに0が代入され、第1引数の変数に変換結果が代入されます。
// 変換に失敗するとstatに1が代入されます。
#deffunc eng2jp var result, str before, local after
rss2load after, "http://pipes.yahoo.com/poolmmjp/ej_translation_api?_render=rss&text=" + before
if (stat == 0)&(length(after) == 2) {
// after(0)にはAPIの説明が代入されている
result = after(1)
return 0
} else {
return 1
}
#global
rss2load_init@mod_translate
// モジュールここまで
target = "Good morning! How are you today?", "I'm fine, thank you. And you?", "So so."
foreach target
mes target(cnt)
eng2jp result, target(cnt)
if stat == 0 : mes "-> " + result
loop
stop
2008年1月3日木曜日
IEコンポのジャンプ先URLを取得する
HHXソースコード解析によるスクリプト。
リンクをクリックしたときにそのジャンプ先URLを取得します。HHXではこのURLを解析して様々な処理を行っています。
広告による読み込み(Javascript)に対しても反応してしまうようです。// 他のファイルにジャンプする時いちいち確認するブラウザのサンプル
// 主にhhx.hspから引用
#include "user32.as"
// ie event
#define DIID_DWebBrowserEvents2 "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"
// exdispid.h
#define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on
#packopt hide 1
// ウィンドウ最大化を可能にする
// 参考 -> http://lhsp.s206.xrea.com/hsp_window.html
screen 0, ginfo_dispx, ginfo_dispy, screen_hide
GetWindowLong hwnd, -16
SetWindowLong hwnd, -16, stat | $10000 | $40000
// ActiveXコントロール(IEコンポーネント)の配置
axobj ieBrowser, "Shell.Explorer.2"
idIE = stat
if idIE == -1 {
dialog "ActiveXコントロールの配置に失敗しました。", 1
end
}
ieBrowser->"Navigate" "http://www.yahoo.co.jp/"
// 割り込み設定
comevent ieEvent, ieBrowser, DIID_DWebBrowserEvents2, *event_ie
oncmd gosub *event_resize, 0x0005
onexit goto *exit
width 640, 480
gsel 0, 1
stop
// COMイベント発生時のジャンプ先
*event_ie
if comevdisp(ieEvent) == DISPID_BEFORENAVIGATE2 {
// URLを取得
comevarg newurl, ieEvent, 1, 1
dialog newurl + "\nを開こうとしています。開きますか?", 2
if stat == 7 {
// 「いいえ」の場合はNAVIGATEをキャンセル
comevarg Cancel, ieEvent, 6, 2
Cancel("val") = 1
delcom Cancel
}
}
return
// ウィンドウのリサイズ
*event_resize
MoveWindow objinfo(idIE, 2), 0, 0, ginfo_winx, ginfo_winy, 1
return
// プログラムの終了処理
*exit
oncmd 0 : onexit 0
delcom ieEvent
delcom ieBrowser
end
2007年12月25日火曜日
正規表現を利用したURL&メールアドレスのタグ付け
テキストに含まれるURLやメールアドレスにリンクタグ(aタグ)をつけます。
当初は1バイトずつ切りだして判定する方法を利用していたのですが、分かりづらい上に作りにくかったので正規表現を利用したものに切り替えました。ロジックを書かなくて済む分、かなりシンプルなスクリプトになっています。独自のWikiやBBSなどに利用できるかもしれません。// 正規表現を利用したURL&メルアドのタグ付け
#module
// 置換処理のメイン部分
#deffunc do_cnv str before, var after, str pattern, str replace
newcom regexp, "VBScript.RegExp"
comres after
regexp("Pattern") = pattern
regexp("Global") = 1
regexp -> "Replace" before, replace
delcom regexp
return
// URLのタグ付け
#defcfunc add_link str before
do_cnv before, after, "(http://[-/.~_#0-9a-zA-Z]+)", "<a href=\"$1\">$1</a>"
return after
// メールアドレスのタグ付け
#defcfunc add_mailto str before
do_cnv before, after, "([-/.~_0-9a-zA-Z]+@[-.~_0-9a-zA-Z]+)", "<a href=\"mailto:$1\">$1</a>"
return after
#global
// URLにリンク(日本語ドメイン非対応)
before = {"文字列中のURL(URI)にリンクします
HSPTV!(http://hsp.tv/)
HSP開発wiki(http://hspdev-wiki.net/)
http://だけではリンクされません"}
after1 = add_link(before)
mesbox after1, ginfo_winx, ginfo_winy / 2
// メールアドレスにリンク
before = {"文字列中のメールアドレスにリンクします
例えばsample2007@yaboo.co.jpとか!"}
after2 = add_mailto(before)
mesbox after2, ginfo_winx, ginfo_winy / 2
stop
2007年11月29日木曜日
Excelによる円グラフの描画
先ほどアップしたスクリプトは円グラフのサンプルとしては分かりづらかったので、よりシンプルなものを作成しました。
なお棒グラフの描画はHSP-NEXTさんにサンプルがあります。// 参考
// ・日経ソフトウェア 2008年1月号
// ・HSP-NEXT HSPサンプル蔵(COMオブジェクト編)
// http://hspnext.com/hspkura/hspkura11.htm
newcom xlApp, "Excel.Application"
xlApp("Visible") = 1 // ウィンドウを表示
xlApp("DisplayAlerts") = 0 // 警告メッセージを表示させない
xlBooks = xlApp("Workbooks") // Workbooks コレクション取得
xlBook = xlBooks("Add") // ワークブックを追加
xlSheet = xlBook("Worksheets", "sheet1") // シート取得
// データの書き込み
repeat 5
xlRange = xlSheet("Range", "A" + (cnt + 1)) // 代入先セルの指定
xlRange("Value") = rnd(70) + 30 // 値の代入
loop
// グラフの作成
xlCharts = xlApp("Charts")
xlChart = xlCharts("Add")
xlChart("ChartType") = 5 // 円グラフ(xlPie = 5)
xlRange = xlSheet("Range", "A1:A5") // データの範囲
xlChart -> "SetSourceData" xlRange, 2 // グラフの元データを指定
xlChart -> "Location" 2, "sheet1" // グラフの位置(既存のシートに貼り付け)
// COMオブジェクト型変数の破棄
delcom xlRange : delcom xlChart
delcom xlCharts : delcom xlSheet
delcom xlBook : delcom xlBooks
delcom xlApp
stop
拡張子ごとの合計ファイルサイズを求める
任意のフォルダ内にあるファイルのサイズを取得し、拡張子ごとに分類・合計して出力します。
最もサイズの大きいファイルが調べられて、少し楽しいかも知れません。私の場合は素材として保存してあるBMPファイルが最大でした。HSPスクリプトは60MB、ちょっと少ないかも知れません。// 参考
// ・日経ソフトウェア 2008年1月号
// ・HSP開発wiki COMDictionary
// http://hspwiki.tm.land.to/?COMDictionary
// ・HSP-NEXT HSPサンプル蔵(COMオブジェクト編)
// http://hspnext.com/hspkura/hspkura11.htm
#include "hspext.as"
// Dictionaryの準備
newcom dc, "Scripting.Dictionary"
comres comret
dc("compareMode") = 1 // 大文字・小文字を同一視
sdim exts, 8, 10 // 拡張子名を代入する配列変数
ext_num = 0 // 拡張子の種類数
// 処理開始
gosub *select_folder // 検索対象フォルダの指定
gosub *get_data // ファイルを検索しデータを作成
gosub *make_graph // Excelによるグラフの作成
// Dicitonaryの破棄
delcom dc
end
*select_folder
target_folder = ""
selfolder target_folder, ""
if stat == 1 {
dialog "フォルダの選択がキャンセルされました。"
end
}
return
*get_data
mes "データを取得しています..."
notesel file_list
sdim file_list, 1024
sdim folder_names, 256, 10
sdim file_name, 256
sdim folder_name, 256
folder_names(0) = target_folder
folder_num = 0
// 選択したフォルダの中にあるファイルをすべて検索
// 再帰を利用しない方法
repeat
chdir folder_names(folder_num)
// ファイル一覧を取得
dirlist file_list, "*", 1
repeat stat
noteget file_name, cnt
exist file_name
if strsize > 0 {
file_size = strsize
ext = getpath(file_name, 2) // 拡張子を取り出す
dc -> "Exists" ext
if comret {
// すでにデータが存在している場合
file_size += dc("Item", ext)
dc -> "Remove" ext // Itemプロパティに対する上書きがうまくいかないので、いったん消去
} else {
// まだデータが存在していない場合
exts(ext_num) = ext
ext_num++
}
dc -> "Add" ext, file_size
}
loop
// フォルダー一覧を取得
dirlist file_list, "*", 5
folder_num--
repeat stat
// カレントフォルダにあるフォルダの名前を
// ひとつずつfolder_namesへ代入
folder_num++
noteget folder_name, cnt
folder_names(folder_num) = dir_cur + "\\" + folder_name
loop
if folder_num < 0 : break
await 1
loop
mes "データ取得が終了しました。"
return
*make_graph
mes "グラフを作成しています..."
newcom xlApp, "Excel.Application"
xlApp("Visible") = 1 // ウィンドウを表示
xlApp("DisplayAlerts") = 0 // 警告メッセージを表示させない
xlBooks = xlApp("Workbooks") // Workbooks コレクション取得
xlBook = xlBooks("Add") // ワークブックを追加
xlSheet = xlBook("Worksheets", "sheet1") // シート取得
// データの書き込み(拡張子ごとのデータ)
repeat ext_num
xlRange = xlSheet("Range", "A" + (cnt + 1)) // 代入先セルの指定
xlRange("Value") = exts(cnt) // 値の代入
xlRange = xlSheet("Range", "B" + (cnt + 1)) // 代入先セルの指定
xlRange("Value") = dc("Item", exts(cnt)) // 値の代入
loop
// データの書き込み(合計値の算出)
xlRange = xlSheet("Range", "A" + (ext_num + 1)) // 代入先セルの指定
xlRange("Value") = "合計" // 値の代入
xlRange = xlSheet("Range", "B" + (ext_num + 1)) // 代入先セルの指定
xlRange("Value") = "=SUM(A1:B" + ext_num + ")" // 値の代入
// グラフの作成
xlCharts = xlApp("Charts")
xlChart = xlCharts("Add")
xlChart("ChartType") = 5 // 円グラフ
xlRange = xlSheet("Range", "A1:B" + ext_num) // データの範囲
xlChart -> "SetSourceData" xlRange, 2 // グラフの元データを指定
xlChart -> "Location" 2, "sheet1" // グラフの位置(既存のシートに貼り付け)
// COMオブジェクト型変数の破棄
delcom xlRange : delcom xlChart
delcom xlCharts : delcom xlSheet
delcom xlBook : delcom xlBooks
delcom xlApp
mes "グラフを作成しました。"
return
2007年11月27日火曜日
IEコンポーネントによるRSSリーダー
本家BBSにて、動的にHTMLを記述するスクリプトを見て作成。
IEはあまり好きではないのですが(普段はFxを使用)、ほぼすべての環境で動作する点が長所ですね。
hspailさんのスクリプトをほぼそのまま流用しています(感謝!)が、とても基本的なスクリプトなので著作権は発生しないと考え、無許可で載せています。
ついでにmod_rss.asを利用してみました。mod_rss.as内部ではCOMを利用しています。#include "mod_rss.as"
// RSSリーダーサンプル
// 付属サンプル(rssload.hsp)を改造
// また、HSPTV!のBBSよりhspailさんのスクリプトを参考とさせていただきました。
title "Loading..."
url="http://hspwiki.tm.land.to/?cmd=rss&ver=1.0"
rssload desc, link, url, 15
if stat == 1 : dialog "取得に失敗しました。" : end
if stat == 2 : dialog "RSSではありません。" : end
axobj ie, "Shell.Explorer.2", ginfo_winx, ginfo_winy
if stat == -1 {
dialog "ActiveXコントロールの配置に失敗しました。", 1
end
}
title url
code = {"<html><body>
\t<p>クリックすると別ウィンドウでリンク先を開きます。</p>
\t<ol>\n"}
foreach desc
code += "\t<li><a href=\"" + link(cnt) + "\" target=\"_blank\">" + desc(cnt) + "</a></li>\n"
loop
code += "\t</ol>\n</body></html>"
ie -> "Navigate" "about:blank"
doc = ie("Document")
doc -> "write" code
stop
2007年9月21日金曜日
動的SQLによる数独の超高速解法(by CodeZine)
SQLele利用スクリプト第4弾。
みんな大好きCodeZine様より転載しました。元記事は動的SQLによる数独の超高速解法。よって今回の記事を利用する場合はCodeZine様の規約に従ってください。
元記事の章・節に合わせたコメントが付いています。
……しかしこれはすごいですね。
SQLで数独を解くという発想もさることながら、その速度が充分実用的な点に驚かされます。
解法が複数ある場合でもすべて示してくれるのも素晴らしいです。
WHERE節の条件重複を回避するためにxnoteaddを利用しようとしたのですが、原因不明のエラーで落ちてしまうので独自命令で対応しています。生成されるSQL文を元記事と全く同じにするためにはWHERE節のソートも必要だったのですが、sortnoteの仕様(空行追加)がややこしかったので考慮していません。// http://codezine.jp/a/article/aid/1629.aspx
// 動的SQLによる数独の超高速解法
#runtime "hsp3cl"
#include "sqlele.hsp"
#module
// 文字列の置換(参考:サンプルスクリプトcompbj/comtest9.hsp)
#deffunc replace var target, str before, str after
newcom o_reg, "VBScript.RegExp"
comres target
o_reg( "Pattern" ) = before // 検索パターンの設定
o_reg( "Global" ) = 1 // すべて置換する
o_reg -> "Replace" target, after // 検索の実行
delcom o_reg
return
// xnoteadd代替命令(今回は問題ないが、完全互換ではない点に注意)
#deffunc xnoteadd_ var target, str add
if instr( target, 0, add + "\n" ) < 0 {
target += add + "\n"
}
return
#global
dim problem, 9, 9
problem(0, 0) = 1,0,0,0,0,7,0,9,0
problem(0, 1) = 0,3,0,0,2,0,0,0,8
problem(0, 2) = 0,0,9,6,0,0,5,0,0
problem(0, 3) = 0,0,5,3,0,0,9,0,0
problem(0, 4) = 0,1,0,0,8,0,0,0,2
problem(0, 5) = 6,0,0,0,0,4,0,0,0
problem(0, 6) = 3,0,0,0,0,0,0,1,0
problem(0, 7) = 0,4,0,0,0,0,0,0,7
problem(0, 8) = 0,0,7,0,0,0,3,0,0
max_num = length( problem )
m = int( sqrt( length( problem ) ) )
sdim select_items, 6400
sdim from_items, 6400
sdim where_items, 30000
// SELECT文の生成
for row1, 0, max_num
for col1, 0, max_num
label1 = "R" + ( row1 + 1 ) + "C" + ( col1 + 1 )
// SELECT節
if problem( col1, row1 ) != 0 {
item1 = str( problem( col1, row1 ) )
} else {
item1 = "t" + label1 + ".n"
}
select_items += item1 + " AS " + label1 + ","
// FROM節
if problem( col1, row1 ) == 0 {
from_items += "nums t" + label1 + ","
}
// WHERE節
for row2, 0, max_num
for col2, 0, max_num
if ( problem( col1, row1 ) == 0 ) | ( problem( col2, row2 ) == 0 ) {
if (( row1 == row2 ) & ( col1 != col2 )) | (( row1 != row2 ) & ( col1 == col2 )) | (( row1 != row2 ) & ( col1 != col2 ) & ( row1 / m == row2 / m ) & ( col1 / m == col2 / m )) {
label2 = "R" + ( row2 + 1 ) + "C" + ( col2 + 1 )
if problem( col2, row2 ) != 0 {
item2 = str( problem( col2, row2 ) )
} else {
item2 = "t" + label2 + ".n"
}
if ( item1 != item2 ) < 0 {
xnoteadd_ where_items, item1 + "!=" + item2
} else {
xnoteadd_ where_items, item2 + "!=" + item1
}
}
}
next
next
next
next
// SELECTの完成
sdim sql, 30000
poke select_items, strlen( select_items ) - strlen( "," ), 0 // 最後の余計なカンマを削除
poke from_items, strlen( from_items ) - strlen( "," ), 0 // 最後の余計なカンマを削除
replace where_items, "\\n", " AND " // 改行を削除
poke where_items, strlen( where_items ) - strlen( " AND " ), 0 // 最後の余計なANDを削除
sql = "SELECT " + select_items + " FROM " + from_items + " WHERE " + where_items
; notesel sql : notesave "sql.txt"
// クエリの実行
// テーブル:numsの準備
sql_open ":memory:"
sql_q "CREATE TABLE nums (n INTEGER NOT NULL PRIMARY KEY);"
repeat 9, 1
sql_q "INSERT INTO nums VALUES (" + prm_i(cnt) + ");"
loop
// 結果の取得
sql_q sql
repeat stat, 1
mes "Solution No." + cnt
for r, 0, max_num
s = ""
for c, 0, max_num
s += strf("%1d ", sql_i( "R" + ( r + 1 ) + "C" + ( c + 1 ) ) )
next
mes s
next
sql_next
loop
sql_close
stop
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 0, 380, 200
objmode 1, 1
syscolor 5 : boxf
syscolor 8 : sysfont 17
pos 30, 30 : mes "対象ファイル"
pos 30, 70 : mes "保存先フォルダ"
pos 30, 110 : mes "ショートカットの名前"
objsize 160
pos 130, 27 : input fnTarget : idInputTargetName = stat
pos 130, 67 : input dnShortcut : idInputDirectoryName = stat
pos 130, 107 : input fnShortcut : idInputShortcutName = stat
objsize 60
pos 290, 27 : button gosub "選択", *selectTarget
pos 290, 67 : button gosub "選択", *selectDirectory
pos 290, 107 : button gosub "選択", *selectShortcut
objsize 320, 40
pos 30, 150 : 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(refstr, 1) + ".lnk"
objprm idInputShortcutName, fnShortcut
}
return