全然更新しないブログ
HSPメモ帳
再利用1
HSP Ver3.3
#include
#includeで、指定ファイルのコードを挿入できます。ファイル内容は、「#define等を使った定義」、「#deffunc等を使った関数」、「モジュール定義」、「DLLの定義」、「COMの定義」等の組み合わせが考えられます。
関数
例えば、コード1,2のようにグローバル空間に記述するコードをインクルードすることは、再利用という点で考えると良くありません。コード1 - main.hsp
#include "sub1.hsp" // サイズ変更可能ウィンドウの作成 stop
コード2 - sub1.hsp
#uselib "user32.dll" #func GetWindowLong "GetWindowLongA" int,int #func SetWindowLong "SetWindowLongA" int,int,int #func SetWindowPos "SetWindowPos" int,int,int,int,int,int,int screen 0, ginfo_dispx , ginfo_dispy, 0, -1, -1, 300, 300 title "Sample" GetWindowLong hwnd, -16 SetWindowLong hwnd, -16 , stat | 0x50000 SetWindowPos hwnd, 0, 0, 0, 0, 0, 0x23
コード3,4のように関数化することで、別のプログラムでも利用しやすくなります。また、コード2で#uselibを使用してDLLの関数定義をしていますが、いい方法とは言えません。他のプログラムで同じ関数を定義した場合、重複定義でエラーとなります。user32.asのように一つのDLL内の関数をまとめて定義して、重複定義されないようにする必要があります。#module内に関数定義することで重複してもエラーにはなりませんが、AXファイルが大きくなることがあります。例として、3つのモジュール内で同じ関数を3つ定義していた場合のAXサイズは、753バイト、グローバルで定義した場合のAXサイズは、509バイト。防止策として、DLL関数やCOMの定義等は、モジュール外にglobalで定義する方法があります。
コード3 - main.hsp
#include "WndFunc.hsp" #define MAIN_TITLENAME "Sapmle" CreateSizeboxWnd 0, -1, -1, 300, 300 title MAIN_TITLENAME stop
コード4 - WndFunc.hsp
#ifndef WNDFUNC_HSP_ // 二重定義防止のため
#define WNDFUNC_HSP_ // 二重定義防止のため
#include "user32.as"
#module
#defcfunc SetWndStyle int st
SetWindowLong hwnd, -16 , st
if ( stat == 0 ){ return 0 }
SetWindowPos hwnd, 0, 0, 0, 0, 0, 0x23
if ( stat == 0 ){ return 0 }
return 1
#deffunc CreateSizeboxWnd int id, int x, int y, int w, int h
screen id, ginfo_dispx , ginfo_dispy, 0, x, y, w, h
GetWindowLong hwnd, -16
return SetWndStyle(stat | 0x50000)
#global
#endif // 二重定義防止のため#addition
似た命令で、#additionがあります。これは、指定ファイルがなくてもエラーとなりません。HSPフォルダのcommon、sampleフォルダを検索してみましたが使用されているのは、hspdef.asの#addition "userdef.as" だけでした。使いどころが難しいのかあまり使われてないようです。注意
#に続く文字は、全て小文字である必要があります。大文字が含まれる場合、エラーも出ずインクルードもされないので注意。(Ver2.6はエラーになりました)最適化
| history.txtから引用 |
|
| AXファイルのサイズ比較 - HSP Ver 3.2 | |||||||||
コードを記述しない白紙の状態でAXファイルを作成した場合のサイズは、114byte。関数の定義だけでは、AXサイズは変わらず、呼び出した関数名のみ登録されます。モジュールの場合、モジュール内の命令・関数を一つでも呼び出された場合モジュール内全てが登録されるようです。
|
| 最適化によるラベル無効の例 | ||
| モジュール内にラベルを使用している場合注意が必要です。以下サンプルです。モジュール「mod1」のラベルがモジュール「mod2」の「Func4」命令で使用されていますが、「mod1」の「Func3」命令がサンプル内で使用されていない為に最適化により「mod1」は無視されます。よって、コンパイルエラー error 19 : 致命的なエラーです
|
改行コード
実行環境
今回の記事内のコードはHSPの3.1と3.2のリリースバージョンで実行しています。新しいバージョンでは再現できない可能性があります。
文字コード
コード内で、クォーテンションである「'」で囲んだ時の1文字目の文字コードを意味します。つまり、
上記のコードの「code1」と「code2」は同じ値が代入されます。「code1」と「code2」は、16進数整数で、0x61が代入されます。「code2」には、0x6162は代入されません。
code1 = 'a'
code2 = 'ab'
code2 = 'ab'
上記のコードの「code1」と「code2」は同じ値が代入されます。「code1」と「code2」は、16進数整数で、0x61が代入されます。「code2」には、0x6162は代入されません。
改行コード
次に、以下のコードを実行してみます。
code1 = '¥r'
code2 = '¥n'
code2 = '¥n'
16進数で、「code1」に0x0d、「code2」に0x0dが代入されます。一般的には、「¥r」は、0x0d、「¥n」は、0x0aです。もし、'¥n'をコード内で書いた場合に間違った結果となる可能性があります。例を以下のコードで示します。内容は、改行の次の文字を?に変更しています。
buf = {"123
456
789"}
repeat strlen(buf)
if( peek(buf, cnt) == '¥n' ){
if( peek(buf, cnt + 1) == 0 ){ break }
poke buf, cnt + 1, '?'
}
loop
mes buf上記コードのbufの結果。'¥n'の箇所に?が代入されています。
123
?456
?789
?456
?789
'¥n'を、0x0aに変更することで、期待したbufを取得できます。
123
?56
?89
?56
?89
XML
| XML DOMメモ ※varuseでcomresの変数チェック等を省略しています。 |
| ファイルの作成 スクリプトの文字列変数から、ファイルを作成。asyncプロパティは、1が非同期ダウンロード、0が同期。デフォルトは1。非同期の場合、loadメソッドはすべての読み込みを完了する前に戻ります。loadXMLメソッドは、指定された文字列を読み込みます。saveメソッドは、指定したファイル名に保存します。 以下のコードを実行すると、カレントフォルダに「persons.xml」ファイルを保存します。
|
| ファイルの読み込み loadメソッドは、指定したファイル名を読み込みます。
|
| XML宣言 以下のコードは、XML宣言<?xml version="1.0" encoding="UTF-8"?>を挿入しています。createProcessingInstructionメソッドでProcessingInstructionノードを作成(pi)して、insertBeforeメソッドで、指定したXMLDoc("firstChild")の前に挿入します。挿入前のXMLDoc("firstChild")は、「<persons/>」です。 ※mes表示では、encoding…がありませんがデータとして存在します(ファイル参照)。
|
挿入
上記の表のように挿入してみる。追加するだけならばappendChildメソッドを利用する。上記は、見やすいように字下げしています。作成されたファイルをIEで開くと整形されて表示されます。 XPathの指定 setPropertyメソッドで、SelectionLanguageプロパティをXPathに変更。デフォルトはXSLPattern。 挿入する要素の作成 createElementメソッドでperson、name、age要素を作成する。personのsetAttributeメソッドで属性を追加する。createCommentメソッドでコメント要素を作成する。personのappendChildメソッドで、コメント、name、age要素を追加する。 条件1 川崎の前に挿入したい場合 selectSingleNodeメソッドでnameが川崎のperson要素を取得する。insertBeforeメソッドで、要素を挿入する。 条件2 2番目に挿入したい場合 getElementsByTagNameメソッドでperson要素のノードリストを取得する。ノードリストのitemメソッドで2番目の要素を取得する。insertBeforeメソッドで、要素を挿入する。
|
| 要素の削除と変更 nameが坂本のperson要素全体を削除して、nameが青木のageを20に変更します。 removeChildメソッドで削除します。ノードのテキストを変更した場合、子要素も削除されるためにitemを取得して変更しています。
|
OpenClipboardのメモ
| OpenClipboard について |
ヘルプには、以下のように書かれています。
| BOOL OpenClipboard( HWND hWndNewOwner // ウィンドウのハンドル ); hWndNewOwner クリップボードをいて関連付けたいウィンドウのハンドルを指定します。NULL を指定すると、現在のタスクがクリップボードを開きます。 |
| 他のウィンドウが既にクリップボードを開いている場合、OpenClipboard 関数は失敗します。 OpenClipboard の呼び出しに成功するたびに、アプリケーションは CloseClipboard 関数を呼び出すべきです。 EmptyClipboard 関数を呼び出さないと、hWndNewOwner パラメータで指定したウィンドウはクリップボードのオーナーになりません。 |
| 失敗するケース |
OpenClipboardの引数の違い(Windows XP SP3)
| |||||||||||||||||||||||||||||||
表-右下の場合、処理1のOpenClipboard(NULL)が成功しても、処理2のOpenClipboard(NULL)後は処理1のクリップボードの操作が失敗する。
| « 前ページ | 次ページ » |
