内存对话框模版的使用,同时包含IP控件的使用演示:
uses CommCtrl ;
const
ICC_INTERNET_CLASSES = $0800 ;
ICC_PROGRESS_CLASS = $0020 ;
ICC_ANIMATE_CLASS = $0080 ;
IPADDRESS_CLASS = 'SysIPAddress32' ;
PROGRESS_CLASS = 'msctls_progress32' ;
ANIMATE_CLASS = 'SysAnimate32' ;
WM_MESIPBUTTON = WM_USER + 1 ;
WM_MESIPSRBUTTON = WM_USER + 2 ;
IPM_CLEARADDRESS = WM_USER + 100 ;
IPM_SETADDRESS = WM_USER + 101 ;
IPM_GETADDRESS = WM_USER + 102 ;
IPM_SETRANGE = WM_USER + 103 ;
IPM_SETFOCUS = WM_USER + 104 ;
IPM_ISBLANK = WM_USER + 105 ;
IPN_FIELDCHANGED = 200 ;
PBS_SMOOTH = $01 ;
PBS_VERTICAL = $04 ;
PBM_SETRANGE = WM_USER + 1 ;
PBM_SETPOS = WM_USER + 2 ;
PBM_DELTAPOS = WM_USER + 3 ;
PBM_SETSTEP = WM_USER + 4 ;
PBM_STEPIT = WM_USER + 5 ;
PBM_SETRANGE32 = WM_USER + 6 ; // lParam = high, wParam = low
PBM_GETRANGE = WM_USER + 7 ; // wParam = return (TRUE ? low : high). lParam = PPBRANGE or NULL
PBM_GETPOS = WM_USER + 8 ;
PBM_SETBARCOLOR = WM_USER + 9 ; // lParam = bar color
PBM_SETBKCOLOR = $2001 ; // lParam = bkColor
ACS_CENTER = $0001 ;
ACS_TRANSPARENT = $0002 ;
ACS_AUTOPLAY = $0004 ;
ACS_TIMER = $0008 ; // don't use threads... use timers
ACM_OPEN = WM_USER + 100 ;
ACM_OPENW = WM_USER + 103 ;
ACM_PLAY = WM_USER + 101 ;
ACM_STOP = WM_USER + 102 ;
ACN_START = 1 ;
ACN_STOP = 2 ;
PSCB_PRECREATE = 2 ;
ID_IP = 200 ;
ID_EDIT = 201 ;
ID_PROGRESS = 202 ;
ID_ANIMATE = 203 ;
type
TINITCOMMONCONTROLSEX = packed record
dwSize : DWORD ;
dwICC : DWORD ;
end ;
LPINITCOMMONCONTROLSEX = ^ TINITCOMMONCONTROLSEX ;
TNMIPADDRESS = packed record
hdr : TNMHDR ;
iField : WORD ;
iValue : WORD ;
end ;
LPNMIPADDRESS = ^ TNMIPADDRESS ;
TDLGTEMPLATEEX = packed record
dlgVer : WORD ;
signature : WORD ;
helpID : DWORD ;
exStyle : DWORD ;
style : DWORD ;
cDlgItems : WORD ;
x : WORD ;
y : WORD ;
cx : WORD ;
cy : WORD ;
menu : WORD ;
windowClass : WORD ;
title : LPWSTR ;
end ;
PDLGTEMPLATEEX = ^ TDLGTEMPLATEEX ;
function InitCommonControlsEx ( var lpInitCtrls : TINITCOMMONCONTROLSEX ): BOOL ; stdcall ; external 'Comctl32.dll'
function lpwAlign ( lpIn : DWORD ): DWORD ;
var
ul : DWORD ;
begin
ul := lpIn ;
ul := ul + 3 ;
ul := ul shr 2 ;
ul := ul shl 2 ;
Result := ul ;
end ;
function Ip2Str ( val : DWORD ): string ;
begin
Result := IntToStr (( val and $0FF000000 ) shr 24 ) + '.' ;
Result := Result + IntToStr (( val and $000FF0000 ) shr 16 ) + '.' ;
Result := Result + IntToStr (( val and $00000FF00 ) shr 8 ) + '.' ;
Result := Result + IntToStr ( val and $0000000FF );
end ;
function DialogProc ( hwndDlg : HWND ; wmessage : UINT ; wParam : WPARAM ; lParam : LPARAM ): BOOL ; stdcall ;
var
dIP , dlIt , Res : DWORD ;
nmn : LPNMIPADDRESS ;
IPStr : string ;
begin
Result := FALSE ;
case wmessage of
WM_INITDIALOG :
begin
dlIt := GetDlgItem ( hwndDlg , ID_PROGRESS );
SendMessage ( dlIt , PBM_SETRANGE32 , 0 , 100 );
SendMessage ( dlIt , PBM_SETSTEP , 1 , 0 );
SendMessage ( dlIt , PBM_SETBARCOLOR , 0 , RGB ( 255 , 0 , 0 ));
SendMessage ( dlIt , PBM_SETBKCOLOR , 0 , RGB ( 0 , 255 , 0 ));
dlIt := GetDlgItem ( hwndDlg , ID_ANIMATE );
SendMessage ( dlIt , ACM_OPEN , GetModuleHandle ( nil ), 5 );
SendMessage ( dlIt , ACM_PLAY , DWORD (- 1 ), 1 );
Result := True ;
end ;
WM_NOTIFY :
case LOWORD ( wParam ) of
IPN_FIELDCHANGED :
begin
nmn := Pointer ( lparam );
end ;
end ;
WM_COMMAND :
case LOWORD ( wParam ) of
WM_MESIPBUTTON :
begin
dlIt := GetDlgItem ( hwndDlg , ID_IP );
Res := SendMessage ( dlIt , IPM_ISBLANK , 0 , 0 );
if Res <> 0 then
begin
MessageBox ( hwndDlg , PChar ( 'Can''t set ip' ), PChar ( 'Error' ), MB_OK or MB_ICONERROR );
Exit ;
end ;
SendMessage ( GetDlgItem ( hwndDlg , ID_IP ), IPM_GETADDRESS , 0 , DWORD (@ dIp ));
IPStr := Ip2Str ( dIp );
MessageBox ( hwndDlg , PChar ( 'IP = ' + IPStr ), PChar ( 'INfo' ), MB_OK or MB_ICONASTERISK );
SendMessage ( GetDlgItem ( hwndDlg , ID_IP ), IPM_CLEARADDRESS , 0 , 0 );
dlIt := GetDlgItem ( hwndDlg , ID_EDIT );
SendMessage ( dlIt , WM_SETTEXT , 0 , DWORD ( PChar ( IPStr )));
end ;
WM_MESIPSRBUTTON :
begin
dlIt := GetDlgItem ( hwndDlg , ID_IP );
SendMessage ( dlIt , IPM_SETRANGE , 0 , $6432 );
SendMessage ( dlIt , IPM_SETRANGE , 1 , $6432 );
SendMessage ( dlIt , IPM_SETRANGE , 2 , $6432 );
SendMessage ( dlIt , IPM_SETRANGE , 3 , $6432 );
SendMessage ( dlIt , IPM_CLEARADDRESS , 0 , 0 );
SendMessage ( dlIt , IPM_SETFOCUS , 0 , 0 );
MessageBox ( hwndDlg , PChar ( 'IP range = 50..100' ), PChar ( 'Info' ), MB_OK or MB_ICONASTERISK );
end ;
ID_HELP :
MessageBox ( hwndDlg , PChar ( ':-)' ),
PChar ( 'Help...' ), MB_OK or MB_ICONASTERISK );
IDOK , IDCANCEL :
begin
EndDialog ( hwndDlg , wParam );
Result := TRUE ;
end ;
end ;
end ;
end ;
function MakeDialog ( wnd : HWND ): HWND ;
type
TWordArray = array [ 0 .. 100 ] of WORD ;
var
hgbl : HGLOBAL ;
lpdt : PDLGTEMPLATE ;
lpwd : ^ TWordArray ;
lpwsz : LPWSTR ;
lpitOK : PDLGITEMTEMPLATE ;
nchar : BYTE ;
ic : TINITCOMMONCONTROLSEX ;
begin
ic . dwSize := SizeOF ( TINITCOMMONCONTROLSEX );
ic . dwICC := ICC_INTERNET_CLASSES ;
InitCommonControlsEx ( ic );
ic . dwICC := ICC_PROGRESS_CLASS ;
InitCommonControlsEx ( ic );
ic . dwICC := ICC_ANIMATE_CLASS ;
InitCommonControlsEx ( ic );
hgbl := GlobalAlloc ( GMEM_ZEROINIT , 1024 );
lpdt := GlobalLock ( hgbl );
//define dialog
lpdt . style := DS_SETFONT or DS_CENTER or WS_SYSMENU or DS_MODALFRAME or WS_CAPTION or WS_VISIBLE ;
lpdt . cdit := 7 ;
lpdt . x := 10 ;
lpdt . y := 10 ;
lpdt . cx := 140 ;
lpdt . cy := 150 ;
lpwd := Pointer ( DWORD ( lpdt ) + SizeOf ( TDlgTemplate ));
lpwd [ 0 ] := 0 ;
lpwd [ 1 ] := 0 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'IP test dialog' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 8 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 2 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'Ms Sans Serif' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
//-----------------------
// Define an OK button.
//-----------------------
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ))); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 70 ;
lpitOk . cx := 50 ;
lpitOk . cy := 14 ;
lpitOk . id := ID_OK ;
lpitOK . style := WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwd [ 0 ] := $0FFFF ;
lpwd [ 1 ] := $00080 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'OK' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define Help button
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 80 ;
lpitOk . y := 70 ;
lpitOk . cx := 50 ;
lpitOk . cy := 14 ;
lpitOk . id := ID_HELP ;
lpitOK . style := WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwd [ 0 ] := $0FFFF ;
lpwd [ 1 ] := $00080 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'Help' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define IP button
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 50 ;
lpitOk . cx := 50 ;
lpitOk . cy := 14 ;
lpitOk . id := WM_MESIPBUTTON ;
lpitOK . style := WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwd [ 0 ] := $0FFFF ;
lpwd [ 1 ] := $00080 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'Get IP' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define Set range IP button
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 80 ;
lpitOk . y := 50 ;
lpitOk . cx := 50 ;
lpitOk . cy := 14 ;
lpitOk . id := WM_MESIPSRBUTTON ;
lpitOK . style := WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwd [ 0 ] := $0FFFF ;
lpwd [ 1 ] := $00080 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( 'Set IP range' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define Edit control
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 30 ;
lpitOk . cx := 83 ;
lpitOk . cy := 12 ;
lpitOk . id := ID_EDIT ;
lpitOK . style := WS_CHILD or WS_VISIBLE or ES_LEFT or ES_AUTOHSCROLL or WS_BORDER or WS_TABSTOP ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwd [ 0 ] := $0FFFF ;
lpwd [ 1 ] := $00081 ;
lpwsz := Pointer ( DWORD ( lpwd ) + 4 );
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( '' ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define IP control
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 10 ;
lpitOk . cx := 83 ;
lpitOk . cy := 12 ;
lpitOk . id := ID_IP ;
lpitOK . style := WS_CHILDWINDOW or WS_VISIBLE ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwsz := Pointer ( DWORD ( lpwd ));
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( IPADDRESS_CLASS ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define Progress control
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 90 ;
lpitOk . cx := 120 ;
lpitOk . cy := 10 ;
lpitOk . id := ID_PROGRESS ;
lpitOK . style := WS_CHILDWINDOW or WS_VISIBLE or PBS_SMOOTH ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwsz := Pointer ( DWORD ( lpwd ));
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( PROGRESS_CLASS ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
//-----
// Define Animate control
//----
lpwd := Pointer ( lpwAlign ( DWORD ( lpwd ) + 2 )); // align DLGITEMTEMPLATE on DWORD boundary
lpitOK := Pointer ( lpwd );
lpitOk . x := 10 ;
lpitOk . y := 110 ;
lpitOk . cx := 120 ;
lpitOk . cy := 30 ;
lpitOk . id := ID_ANIMATE ;
lpitOK . style := WS_CHILDWINDOW or WS_VISIBLE or ACS_TRANSPARENT or ACS_CENTER or WS_EX_NOPARENTNOTIFY ;
lpwd := Pointer ( DWORD ( lpitOK ) + SizeOf ( TDlgItemTemplate ));
lpwsz := Pointer ( DWORD ( lpwd ));
nchar := MultiByteToWideChar ( CP_ACP , 0 , PChar ( ANIMATE_CLASS ), - 1 , lpwsz , 50 );
lpwd := Pointer ( DWORD ( lpwsz ) + nchar * 2 );
lpwd [ 0 ] := 0 ;
GlobalUnlock ( hgbl );
Result := DialogBoxIndirectA ( hInstance , PDlgTemplate ( hgbl )^, wnd , @ DialogProc );
// Result := CreateDialogIndirect(hInstance, PDlgTemplate(hgbl)^, wnd, @DialogProc);
GlobalFree ( hgbl );
end ;
procedure TForm1 . Button1Click ( Sender : TObject );
begin
MakeDialog ( Handle );
end ;