wikiの3つ目のソースを少し改造したものです。
(そのまま使うとボタンではなくウィンドウ自体の形を変えてしまうので)
画像は円を描画したもので代用しました。
// 不定形リージョンウィンドウ作成
// CreatePolyPolygonRgn使用
// 通常のpget & CreateRectRgnに比べてかなり高速
// ただし、Windows9x系統では正常に動かない可能性あり
// *ぼやき*
// 恐らく一番早いのはExtCreateRectRgn。。。
// けど、引数の内容が面倒なのでこれで妥協
// ちなみにテスト画像は600x690(でか)
// 普通の画像ならかなり早くなるはず
// 必要なものをインクルード
#include "user32.as"
#include "gdi32.as"
#include "winmm.as" // これはリージョン作成に直接関係無し
// ウィンドウ移動制御用の定数
#define global WM_NCLBUTTONDOWN $000000A1
#define global HTCAPTION 2
// リージョン作成用の定数
#define global WINDING 2
// モジュール記述
#module
// CreateWindowRgn p1(targetWin), p2(baseWin), p3(tr), p4(tg), p5(tb)
// targetWin : 不定形リージョンを適用するウィンドウのハンドル
// baseWin : 不定形リージョンを作成する絵があるウィンドウID
// tr, tg, tb: 透過色にするRGB値
#deffunc CreateWindowRgn int targetWin, int baseWin, int tr, int tg, int tb
now_sel = ginfo_sel; // 現在の描画対象ウィンドウIDを記録
gsel baseWin
mref vram, 66 // 画像データを取得
dim pt, 100000 // 点データ用配列
dim ct, 100000 // 多角形点数記憶用配列
wx = ginfo_winx : wy = ginfo_winy // 画像サイズ取得
// 透過色指定の為これらは破棄
;pget 0, 0 // 透明色の取得(点(0,0)の色を透明色にする)
;tr = ginfo_r : tg = ginfo_g : tb = ginfo_b
// 変数初期化
// 注:yはデータ構造上、下から
x = 0 : y = wy : flg = 0 : count = 0 : pt_cnt = 0 : poly_cnt = 0
repeat wy
repeat wx
// 画像データの構造にそってRGB値を取得
b = peek(vram,count)
count++
g = peek(vram,count)
count++
r = peek(vram,count)
count++
// 透明色と比較
// 内部は説明面倒なので省略。やってることはIIと変わらない。
if (wx == x + 1) | ((r == tr) && (g == tg) && (b == tb)) {
if flg == 1 {
pt(pt_cnt) = x, y-1, x, y
pt_cnt += 4
ct(poly_cnt) = 4
poly_cnt++ : flg = 0
}
} else {
if flg == 0 {
pt(pt_cnt) = x, y, x, y-1
pt_cnt += 4
flg = 1
}
}
x++
loop
x = 0
y--
loop
// 取得した情報からリージョン作成(詳細はMSDNやその他サイト参照)
CreatePolyPolygonRgn varptr(pt), varptr(ct), poly_cnt, WINDING
tmpRgn = stat
gsel now_sel // 描画対象ウィンドウを戻す
SetWindowRgn targetWin, tmpRgn, 1 // リージョン設定
DeleteObject tmpRgn // 後片付け
return
#global
// ボタンに乗せる画像1
buffer 10, 192, 64, 0;
color 0, 0, 0: boxf;
color 0, 0, 255;
circle 0, 0, 64, 64, 1;
circle 64, 0, 128, 64, 1;
circle 128, 0, 192, 64, 1;
color 0, 0, 0;
pos 24, 22: mes "素";
pos 88, 22: mes "押";
pos 152, 22:mes "重";
// ボタンに乗せる画像2
buffer 11, 192, 64, 0;
color 0, 0, 0: boxf;
color 0, 255, 0;
circle 0, 0, 64, 64, 1;
circle 64, 0, 128, 64, 1;
circle 128, 0, 192, 64, 1;
color 0, 0, 0;
pos 24, 22: mes "素";
pos 88, 22: mes "押";
pos 152, 22:mes "重";
// 透過色情報用の画像
buffer 12, 64, 64, 0;
color 0, 0, 0: boxf;
color 255, 255, 255: circle 0, 0, 64, 64, 1;
// ウィンドウ作成
screen 0, 300, 200, 0, 0, 0;
title "ID:0";
screen 1, 300, 200, 0, 400, 0;
title "ID:1";
// ウィンドウID 0 にボタンを配置
gsel 0
pos 10, 10
objsize 64, 64
objimage 10, 0,0, 64,0, 128,0;
button gosub "", *btn0
// ボタン等のオブジェクトを作成した直後には stat にオブジェクトIDが入っている
btn_id0 = stat // ボタンのオブジェクトID
btn_hwnd0 = objinfo_hwnd(btn_id0) // オブジェクトIDからウィンドウハンドル取得
// リージョン化(ボタンのウィンドウハンドル、透過情報画像のウィンドウID、透過色RGB値を渡す)
CreateWindowRgn btn_hwnd0, 12, 0, 0, 0;
// ウィンドウID 1 にボタンを配置
gsel 1
pos 20, 10
objsize 64, 64
objimage 11, 0,0, 64,0, 128,0;
button gosub "", *btn1
// オブジェクトIDはウィンドウによってそれぞれ0から順に空いている番号が割り振られる
btn_id1 = stat // ボタンのオブジェクトID
btn_hwnd1 = objinfo_hwnd(btn_id1) // オブジェクトIDからウィンドウハンドル取得
// リージョン化
CreateWindowRgn btn_hwnd1, 12, 0, 0, 0;
*main
gsel 0: gosub *refresh;
gsel 1: gosub *refresh;
await 17;
goto *main;
*refresh
redraw 0;
color 255, 255, 255: boxf;
redraw 1;
return;
*btn0
dialog "ID 0のボタンが押された"
return
*btn1
dialog "ID 1のボタンが押された"
return
一応リージョン化して円形になってるはずなんですが
ボタンの上にマウスが重なったり、ボタンをクリックしたりすると
ときどき四角い形状に戻るという微妙なサンプルになってしまいました。