UWSCのFUKIDASIを多色にする
追記 20120616 XPでも可能な方法を書いたので、本記事は不要。 UWSCのみでFUKIDASIをカラフルにする - じゅんじゅんのきまぐれ でも、シンプルさではこっちが上。
公式掲示板に面白そうな(無意味な)課題があったので、やってみた。
fukidasiの一部だけの文字色変更は残念ながら出来ません (中略) #あるいは何かしらの(おそらく至極面倒な)手段で実現可能かもしれませんが…(略)
前に、検討したんですよね。
結局、callbackが面倒でWM_PAINTを処理できないから、無理、と判断したけど、
何故か、Win7では再描画できてしまったり、、、。
とりあえず、お題の回答
OPTION EXPLICIT DIM fcs[] = $FF0000, $C00040, $800080, $4000C0, $0000FF DIM msg="吹き<#CR>出しで", bc=$00FF00, al=-1 Fukidashi(fcs, msg, G_MOUSE_X, G_MOUSE_Y, 0, 16, "MS ゴシック", bc, al) MSGBOX("OK?") Fukidashi(fcs, msg, G_MOUSE_X, G_MOUSE_Y, 1, 32, "MS Pゴシック", bc, al) MSGBOX("OK?") Fukidashi(fcs, msg, G_MOUSE_X, G_MOUSE_Y, 2, 8, "MS P明朝", bc, al) MSGBOX("OK?") Fukidashi(fcs, msg, G_MOUSE_X, G_MOUSE_Y, 3, 10, "MS 明朝", bc, al) MSGBOX("OK?") Fukidashi(fcs, msg, G_MOUSE_X, G_MOUSE_Y, 4, 72, "MS ゴシック", bc, al) MSGBOX("OK?") // FUKIDASIにあわせる。テキスト色が配列で省略不可 PROCEDURE Fukidashi(fcs[], msg=EMPTY, x=0, y=0, dir=0, pt=10, font="MS Pゴシック", bc=$FFFF, al=0) // WIN32API // テキスト描画用 DEF_DLL GetDC(hwnd): dword: user32 DEF_DLL ReleaseDC(hwnd, dword): int: user32 DEF_DLL DrawTextW(dword, wstring, int, {long, long, long, long}, uint): int: user32 // テキストフォント変更用 DEF_DLL SelectObject(dword, dword): dword: gdi32 DEF_DLL DeleteObject(dword): bool: gdi32 DEF_DLL CreateFontW(int, int, int, int, int, dword, dword, dword, dword, dword, dword, dword, dword, wstring): dword: gdi32 DEF_DLL GetDeviceCaps(dword, int): int: gdi32 DEF_DLL MulDiv(int, int, int): int: kernel32 // 文字色・背景色変更 DEF_DLL SetTextColor(dword, dword): dword: gdi32 DEF_DLL SetBkColor(dword, dword): dword: gdi32 DEF_DLL SetBkMode(dword, int): int: gdi32 // とりあえずFUKIDASIを出して情報収集 DIM fc = 0, fcnum = LENGTH(fcs) IF fcnum > 0 THEN fc = fcs[fcnum-1] FUKIDASI(msg, x, y, dir, pt, font, fc, bc, al) DIM wid = GETID(GET_FUKIDASI_WIN) DIM hwndF = IDTOHND(wid) DIM hdcF = GetDC(hwndF) DIM l = 0, t = 0, r = STATUS(wid, ST_CLWIDTH), b = STATUS(wid, ST_CLHEIGHT) // 微調整 SELECT dir CASE 1 t = 5; b = b + t CASE 2 b = b - 10 CASE 3 l = 5; r = r + l CASE 4 r = r - 10 SELEND // フォント作成とフォント・色設定 DIM ro = r, bo = b, nHeight = MulDiv(pt, GetDeviceCaps(hdcF, 90), 72) DIM hfontF = CreateFontW(0 - nHeight, 0, 0, 0, 0, FALSE, FALSE, FALSE, 0, 0, 0, 0, 0, font) DIM hfontO = SelectObject(hdcF, hfontF) DIM cFr = SetTextColor(hdcF, fc) DIM cBk = SetBkColor(hdcF, bc) DIM cBf = FALSE, cBt IFB al < 0 THEN cBf = TRUE cBt = SetBkMode(hdcF, 1) ENDIF // 描画位置を決定する DIM msgnum = LENGTH(msg) DIM off = DrawTextW(hdcF, msg, msgnum, l, t, r, b, $400) l = l + (ro - r) / 2; r = (ro + r) / 2; ro = r t = t + (bo - b) / 2; b = (bo + b) / 2 // 1文字づつ描く DIM i, tar, lo = l, s = -1 FOR i = 1 TO msgnum tar = COPY(msg, i, 1) IFB tar = CHR(10) THEN t = t + nHeight l = lo s = s - 1 CONTINUE ELSEIF tar = CHR(13) THEN s = s - 1 CONTINUE ENDIF IFB fcnum > i + s THEN SetTextColor(hdcF, fcs[i+s]) ELSE BREAK ENDIF off = DrawTextW(hdcF, tar, 1, l, t, r, b, $400) off = DrawTextW(hdcF, tar, 1, l, t, r, b, 0) // 次の文字の準備 l = r; r = ro NEXT // 後片付け SelectObject(hdcF, hfontO) DeleteObject(hfontF) SetTextColor(hdcF, cFr) SetBkColor(hdcF, cBk) IF cBf THEN SetBkMode(hdcF, cBt) ReleaseDC(hwndF, hdcF) FEND
透明は、SetBkModeかしらん?(未評価)
一度描いただけなので、XPでは再描画が走ると、先頭色になります。
Win7では大丈夫。
VISTAはどっちかな?
追記 20120608
stuncloudさんのコメントによると、vistaも不可。
また、スクリプトを少し修正。
複数行および透明化対応。
、、、でも、本来ならWndProcをフックしてWM_PAINTを処理すべき。
追記 20120613
気になったので、DLL作ってXP/Vistaに対応した。
我ながらアホだと思う。
UWSCのFUKIDASIをカラフルにする - じゅんじゅんのきまぐれ