アイコン無しダイアログ
アイコン無しダイアログ
タイトルバーのアイコン無しのウィンドウって作れるのでしょうか?
WNDCLASS(EX)構造体 の hIcon・hIconSm を NULL にしたり、WM_SETICONでNULLを送るという方法ではダメでした。
何か条件や他の方法があるのでしょうか?
アイコンのない方がダイアログっぽいかなと思いまして…。
WNDCLASS(EX)構造体 の hIcon・hIconSm を NULL にしたり、WM_SETICONでNULLを送るという方法ではダメでした。
何か条件や他の方法があるのでしょうか?
アイコンのない方がダイアログっぽいかなと思いまして…。
Re: アイコン無しダイアログ
方法としては2種類考えられます。
1つは、システムメニューをなくしてしまうことです。
RADツールをお使いなら、「システムメニュー」のチェックを外してください。
ただし、×ボタンも含めたシステムメニューが消えてしまいます。
もう1つは、プログラム中で透明のアイコンを作ってそれをウィンドウに設定することです。
なお、この方法を使う場合はプログラム終了時にDestroyIcon(hIcon)を呼び出す必要があります。また、本来アイコンがあるべき位置に何もなくなるので、ちょっと間が抜けた感じにはなります。
1つは、システムメニューをなくしてしまうことです。
RADツールをお使いなら、「システムメニュー」のチェックを外してください。
ただし、×ボタンも含めたシステムメニューが消えてしまいます。
もう1つは、プログラム中で透明のアイコンを作ってそれをウィンドウに設定することです。
コード: 全て選択
Dim hIcon As HICON
Dim AndBits[31] As Byte,XorBits[31] As Byte
FillMemory(AndBits,32,&HFF)
FillMemory(XorBits,32,&H00)
hIcon=CreateIcon(CreateStruct.hInstance,16,16,1,1,AndBits,XorBits)
SetClassLong(hMainWnd,GCL_HICONSM,hIcon) 'ウィンドウハンドルは適宜変更してください
[hira]
http://hira.hopto.org/
http://hira.hopto.org/
Re: う~ん
根本的な解決ではないかもしれませんが、RADで「拡張スタイルを設定」→「ツールウィンドウ」にチェックを入れると、アイコン無し、×ボタン付きのウィンドウが作れます。
ただ、タイトルバーの高さが半分ぐらいになるんですけどね(^^;
※そんな抜け道しか思いつかんのか、自分(爆)
ただ、タイトルバーの高さが半分ぐらいになるんですけどね(^^;
※そんな抜け道しか思いつかんのか、自分(爆)
[hira]
http://hira.hopto.org/
http://hira.hopto.org/
Cなどのプログラムのダイアログはリソースとして保持していて、それを元にWinAPIのDialogBoxParam/CreateDialogParam関数で作成しています。
ABの場合はダイアログも通常のウィンドウと同じようにRegisterClassEx/CreateWindowExで作成している(そしてABプロジェクトが自動で作成するファイル内でDialogBox/CreateDialogを実装している)ためアイコンが表示されてしまいます。
ちなみにCreateDialogIndirectParam/CreateDialogIndirectParamというリソースの代わりにDLGTEMPLATE構造体を用意してこれを元にダイアログを表示するという関数もあります。
しかしこれではRADツールを使えないので非現実的です。
ABのRADがこれかリソースに対応してもらえれば一番良いのですけどね。
こうすれば解決します、というような話でなくてすみませんが。
ABの場合はダイアログも通常のウィンドウと同じようにRegisterClassEx/CreateWindowExで作成している(そしてABプロジェクトが自動で作成するファイル内でDialogBox/CreateDialogを実装している)ためアイコンが表示されてしまいます。
ちなみにCreateDialogIndirectParam/CreateDialogIndirectParamというリソースの代わりにDLGTEMPLATE構造体を用意してこれを元にダイアログを表示するという関数もあります。
しかしこれではRADツールを使えないので非現実的です。
ABのRADがこれかリソースに対応してもらえれば一番良いのですけどね。
こうすれば解決します、というような話でなくてすみませんが。
Re: う~ん
> 根本的な解決ではないかもしれませんが、RADで「拡張スタイルを設定」→「ツールウィンドウ」にチェックを入れると、アイコン無し、×ボタン付きのウィンドウが作れます。
> ただ、タイトルバーの高さが半分ぐらいになるんですけどね(^^;
> ※そんな抜け道しか思いつかんのか、自分(爆)
でも、ツールウィンドゥになった場合メインが対象だと、タスクバーにプログラムが出ませんから、かえって面倒ですよね
(これは、僕が体験済みやった自分で終了時面倒くさくなりました)
> ただ、タイトルバーの高さが半分ぐらいになるんですけどね(^^;
> ※そんな抜け道しか思いつかんのか、自分(爆)
でも、ツールウィンドゥになった場合メインが対象だと、タスクバーにプログラムが出ませんから、かえって面倒ですよね
(これは、僕が体験済みやった自分で終了時面倒くさくなりました)
Re: う~ん
> やっぱりそういう方法しかないみたいですね。
> クローズボタンのみってのができればいいんですけど…。
>
> Cではリソースでダイアログを作成したりするとアイコンなしのが作れますよね。
> あれはまた何か特殊だったりするのでしょうか?
>
> とりあえずはアイコン有りでやっていこうかと思います。
> 有難う御座いました。
私の意見はあんまり参考にはならないかもしれませんが
タイトルバーを自作してしまう手もありますよ。
って、こっちの方が面倒か(笑
そのやり方ですが、
多分、WM_NCPAINTメッセージをひろって
Draw~~系のAPIで描画すればいいんではないかと思います。
> クローズボタンのみってのができればいいんですけど…。
>
> Cではリソースでダイアログを作成したりするとアイコンなしのが作れますよね。
> あれはまた何か特殊だったりするのでしょうか?
>
> とりあえずはアイコン有りでやっていこうかと思います。
> 有難う御座いました。
私の意見はあんまり参考にはならないかもしれませんが
タイトルバーを自作してしまう手もありますよ。
って、こっちの方が面倒か(笑
そのやり方ですが、
多分、WM_NCPAINTメッセージをひろって
Draw~~系のAPIで描画すればいいんではないかと思います。
Re: う~ん
この可変長配列って、たぶんコントロール(ボタンとかエディットボックスとか)だと思います。> DialogBoxIndirectParam関数を調べてみましたが、かなり大変ですね。
>
> DLGTEMPLATE構造体の後につけなければならないという可変長配列もあまりはっきりとわからないし…。
RADで作ってくれるコントロール群はすべてCreateWindowEx関数を使用してますので、ダイアログのウィンドウだけDialogBoxIndirectParam関数で作ってしまってCallbackはRADのものを使うことができます。
追記です。
CallbackはRADのものを使えると書きましたが、ABのダイアログプロシージャとAPIのプロシージャは少し内容が違うので難しいかもしれません。
何かいい方法があればいいのですが...
自分はDLGTEMPLATE構造体を使ってウィザードを作ったことがあるので、たぶんいけると思います。
http://dbp.cool.ne.jp/patio/patio.cgi?mode=view&no=207
過去ログにDialogBoxIndirectParam関数とDLGTEMPLATE構造体を使用したダイアログ作成法が載っていたと思いますので、探してみてください。(No.1801)
P.S. 注意点というかアドバイスをすこし...
1. DLGTEMPLATE構造体はそのままのサイズでは動きません。
Dim dlg As DLGTEMPLATE などとしてもエラーになります。
上の高信期さんのサンプルでは
PTemplate = calloc(30) 'sizeof(DLGTEMPLATE) + 10
となっていますが、sizeof(DLGTEMPLATE) + sizeof(WORD)*2 + sizeof(WCHAR) = sizeof(DLGTEMPLATE) + 6 = 24バイト 以上のサイズがあれば動くみたいです。(DLGTEMPLATE構造体のサイズは実際は18バイトです。)
2.DLGTEMPLATE構造体に指定するx, cxなどのメンバはCのリソースと同じダイアログボックス単位(?うろ覚え)になってます。
そのためサイズ合わせが面倒ですので、RADツールに表示されるウィンドウサイズをコピってCreateイベントでMoveWindow, SetWindowPosあたりを呼んでサイズ変更するのが簡単かと思います。
最後に編集したユーザー Tomorrow [ 2005年7月30日(土) 19:28 ], 累計 1 回
RADのダイアログをDialogBoxIndirectParamで
なんとか表示させるところまでは漕ぎつけたましたが、それを終了させたらなぜかアプリケーション自体が終了してしまう……。
ダイアログアプリケーションならそれでも気になりませんが。
(ウィンドウMainWndにボタンを1つ置き、それを押すとダイアログDlgをDialogBoxIndirectParamで作成するという具合。ダイアログボックスにウィンドウクラスを指定したのがまずかったのかと考えてみたり)
ダイアログアプリケーションならそれでも気になりませんが。
(ウィンドウMainWndにボタンを1つ置き、それを押すとダイアログDlgをDialogBoxIndirectParamで作成するという具合。ダイアログボックスにウィンドウクラスを指定したのがまずかったのかと考えてみたり)
コード: 全て選択
'dlg.sbp
Const DLGCLASS = "DlgTest"
Function InitDialog(hInstance As HINSTANCE, pszClassName As BytePtr) As Long
Dim wcx As WNDCLASSEX
With wcx
.cbSize = Len(wcx)
.style = CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS
.lpfnWndProc = AddressOf(DlgProc)
.cbWndExtra = DLGWINDOWEXTRA
.hInstance = hInstance
.hCursor = LoadCursor(NULL, IDC_ARROW)
.hbrBackground = h3DFaceBrush
.lpszClassName = pszClassName
End With
RegisterClassEx(wcx)
End Function
Function DialogBoxEx(hInstance As HINSTANCE, pszClassName As BytePtr) As Long
Dim cchClassNameA As Long, cchClassNameW As Long
cchClassNameA = lstrlen(pszClassName)
cchClassNameW = MultiByteToWideChar(CP_ACP, 0, pszClassName, cchClassNameA, NULL, 0)
Dim pDialog As *DLGTEMPLATEEX
pDialog = calloc(SizeOf(DLGTEMPLATEEX) + SizeOf(WCHAR) * (2 + cchClassNameW))
With pDialog[0]
.dlgVer = 1
.signature = &hffff
.helpID = 0
.exStyle = WS_EX_DLGMODALFRAME Or WS_EX_WINDOWEDGE Or WS_EX_CONTROLPARENT
.style = WS_POPUPWINDOW Or WS_VISIBLE Or WS_CLIPSIBLINGS Or DS_MODALFRAME Or WS_CAPTION
.x = 20
.y = 20
.cx = 180
.cy = 120
End With
Dim pDlgClassName As *WCHAR
pDlgClassName = VarPtr(pDialog[1]) + SizeOf (WCHAR)
MultiByteToWideChar(CP_ACP, 0, pszClassName, cchClassNameA, pDlgClassName, cchClassNameW)
DialogBoxIndirectParamEx(hInstance, pDialog, NULL, NULL, 0)'AddressOf(DlgProc), 0)
free(pDialog)
End Function
Const DLGWINDOWEXTRA = 30
TypeDef WPARAM = DWord
TypeDef LPARAM = Long
TypeDef LRESULT = LPARAM
TypeDef INT_PTR = Long
TypeDef DLGPROC = VoidPtr
Declare Function DialogBoxIndirectParamEx Lib "user32" Alias "DialogBoxIndirectParamA" (
ByVal hInstance As HINSTANCE,
ByVal DialogTemplate As *DLGTEMPLATEEX,
ByVal hwndParent As HWND,
ByVal pDialogFunc As DLGPROC,
ByVal InitParam As LPARAM) As Long
Declare Function EndDialogAPI Lib "user32" Alias "EndDialog" (hwndDlg As HWND, nRet As Long) As Long
Type DLGTEMPLATEEX
dlgVer As Word
signature As Word
helpID As DWord
exStyle As DWord
style As DWord
cDlgItems As Word
x As Integer
y As Integer
cx As Integer
cy As Integer
End Type
Function DlgProc(hwnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
If dwMsg = WM_CREATE Then
SetWindowText(hwnd, "タイトル")
SendMessage(hwnd, WM_INITDIALOG, 0, 0)
DlgProc = 0
Else
' イベントプロシージャの呼び出しを行います。
DlgProc = EventCall_Dlg(hwnd, dwMsg, wParam, lParam)
End If
End Function
Sub Dlg_QueryClose(ByRef cancel As Integer)
EndDialogAPI(hwndDlg, 0)
End Sub
コード: 全て選択
'MainWnd.sbp
Sub MainWnd_CommandButton1_Click()
DialogBoxEx(GetWindowLong(hMainWnd, GWL_HINSTANCE), DLGCLASS)
End Sub
Sub MainWnd_Create(ByRef cs As CREATESTRUCT)
InitDialog(cs.hInstance, DLGCLASS)
End Sub
Re: RADのダイアログをDialogBoxIndirectParamで
できました!!
どうもうまくいかないなと思っていたら、DialogBoxIndirectParam関数の第2引数にメモリオブジェクトハンドルを渡してしまっていました。
どっかのサイトではそんな風になってたんだけどな…。
DLGTEMPLATE構造体の後ろに付加しなければならないのは「メニュー」、「クラス名」、「タイトル名」、「フォントサイズ」、「フォント名」、「DLGITEMTEMPLATE構造体配列」らしいです。
いまいちわからないのはMSDNで書かれていたDWord境界に整列するとか何とか。
可変長配列はWord境界ともあったし、どこからどこまでをどう整列すればいいのかよくわからない…。
あとダイアログプロシージャでは処理しないメッセージをDefWindowProcに渡してはいけないそうです。
ダイアログを閉じたらアプリケーションが終了したのはこれが原因ではないでしょうか。
どうもうまくいかないなと思っていたら、DialogBoxIndirectParam関数の第2引数にメモリオブジェクトハンドルを渡してしまっていました。
どっかのサイトではそんな風になってたんだけどな…。
DLGTEMPLATE構造体の後ろに付加しなければならないのは「メニュー」、「クラス名」、「タイトル名」、「フォントサイズ」、「フォント名」、「DLGITEMTEMPLATE構造体配列」らしいです。
いまいちわからないのはMSDNで書かれていたDWord境界に整列するとか何とか。
可変長配列はWord境界ともあったし、どこからどこまでをどう整列すればいいのかよくわからない…。
あとダイアログプロシージャでは処理しないメッセージをDefWindowProcに渡してはいけないそうです。
ダイアログを閉じたらアプリケーションが終了したのはこれが原因ではないでしょうか。
コード: 全て選択
Type DLGTEMPLATE
style As DWord
dwExtendedStyle As DWord
cdit As Word
x As Integer
y As Integer
cx As Integer
cy As Integer
End Type
Declare Function DialogBoxIndirectParam Lib "user32" Alias "DialogBoxIndirectParamA" (hInstance As HINSTANCE,
hDialogTemplate As *DLGTEMPLATE, hWndParent As HWND, lpDialogFunc As DWord, dwInitParam As DWord) As Long
Declare Function EndDialogAPI Lib "user32" Alias "EndDialog" (hwndDlg As HWND, nRet As Long) As Long
Function DialogBox2(hParent As HWND, x As Integer, y As Integer, cx As Integer, cy As Integer, Name As BytePtr) As Long
Dim WideLen As Long
Dim hMem As HGLOBAL
Dim lpdt As *DLGTEMPLATE
Dim lpWord As WordPtr
WideLen = MultiByteToWideChar(CP_ACP, 1, Name, -1, 0, 0)
hMem = GlobalAlloc(GHND, SizeOf(DLGTEMPLATE)+4+(WideLen*2))
lpdt = GlobalLock(hMem)
lpdt->style = WS_POPUP or WS_CAPTION or WS_SYSMENU or DS_MODALFRAME
lpdt->x = x
lpdt->y = y
lpdt->cx = cx
lpdt->cy = cy
lpWord = lpdt+SizeOf(DLGTEMPLATE)+4
MultiByteToWideChar(CP_ACP, 1, Name, -1, lpWord, WideLen)
GlobalUnlock(hMem)
DialogBoxIndirectParam(GetModuleHandle(0), lpdt, hParent, AddressOf(DialogProc), 0)
GlobalFree(hMem)
End Function
Function DialogProc(hWnd As HWND, dwMsg As DWord, wParam As DWord, lParam As DWord) As Long
Select Case dwMsg
Case WM_CLOSE
EndDialogAPI(hWnd, 0)
DialogProc = 1
Case Else
DialogProc = 0
End Select
End Function
最後に編集したユーザー 真紅 [ 2005年7月31日(日) 17:07 ], 累計 1 回
Re: RADのダイアログをDialogBoxIndirectParamで
> あとダイアログプロシージャでは処理しないメッセージをDefWindowProcに渡してはいけないそうです。
> ダイアログを閉じたらアプリケーションが終了したのはこれが原因ではないでしょうか。
私のコードはウィンドウクラスを登録して、それをDLGTEMPLATEの後ろにウィンドウクラス名を指定したんです。
なのであれはダイアログプロシージャではなく、ウィンドウプロシージャなんです。
#ところでウィンドウクラスの指定はDLGTEMPLATEでもできるのに今気づいた。
#自分としてはDLGTEMPLATEEXを使う理由はもうない。
> ダイアログを閉じたらアプリケーションが終了したのはこれが原因ではないでしょうか。
私のコードはウィンドウクラスを登録して、それをDLGTEMPLATEの後ろにウィンドウクラス名を指定したんです。
なのであれはダイアログプロシージャではなく、ウィンドウプロシージャなんです。
#ところでウィンドウクラスの指定はDLGTEMPLATEでもできるのに今気づいた。
#自分としてはDLGTEMPLATEEXを使う理由はもうない。
Re: RADのダイアログをDialogBoxIndirectParamで
> 私のコードはウィンドウクラスを登録して、それをDLGTEMPLATEの後ろにウィンドウクラス名を指定したんです。
> なのであれはダイアログプロシージャではなく、ウィンドウプロシージャなんです。
そうなんですか。
ウィンドウクラスを指定するとダイアログプロシージャではなくなるんですね。
アプリケーションが終了してしまうのは何でだろう…。
> なのであれはダイアログプロシージャではなく、ウィンドウプロシージャなんです。
そうなんですか。
ウィンドウクラスを指定するとダイアログプロシージャではなくなるんですね。
アプリケーションが終了してしまうのは何でだろう…。