News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

TaskDialog

Started by guga, April 10, 2025, 07:17:48 AM

Previous topic - Next topic

sinsi

Quote from: guga on April 10, 2025, 03:05:44 PMI´ll never understand why M$ do such stupidities. Why the hell they put an older version of comclt32 in the default system directory at the 1st place ? The least they could do is put all those newer versions on the default windows system paths.
Surely you remember "DLL hell"?

The manifest lets Windows know which version you want.
SxS is a way of letting different versions of the same DLL co-exist side-by-side  :biggrin:

It's also another abstraction away for the poor C++ programmer

guga

#16
Quote from: sinsi on April 10, 2025, 03:50:54 PM
Quote from: guga on April 10, 2025, 03:05:44 PMI´ll never understand why M$ do such stupidities. Why the hell they put an older version of comclt32 in the default system directory at the 1st place ? The least they could do is put all those newer versions on the default windows system paths.
Surely you remember "DLL hell"?

The manifest lets Windows know which version you want.
SxS is a way of letting different versions of the same DLL co-exist side-by-side  :biggrin:

It's also another abstraction away for the poor C++ programmer

:biggrin:  :biggrin:  :biggrin:

Anyway...i succeeded to make this stuff working without manifest thingies.




I had to use LoadLibraryA and specific the full path to that hidden comctl32 where this Api was located.

I´m posting here the port of this thing to RosAsm. I won´t release the working app, because probably the path of yours should be different than mine. (This could be solved with FindFirstFile pointing to C:\Windows\WinSxS\, then locating all subdirectories where the comctl32 is located and then using GetProcAddress to make sure if that dll contains this damn api). A hell, indeed, without manifest  :dazzled:

The equates and structures for this thing are:

; TaskDialog structures, equates and structures displacements

[TASKDIALOGCONFIG:
 TASKDIALOGCONFIG.cbSize: D$ len                  ; UINT (4 bytes)
 TASKDIALOGCONFIG.hwndParent: D$ 0              ; HWND (4 bytes, ponteiro)
 TASKDIALOGCONFIG.hInstance: D$ 0              ; HINSTANCE (4 bytes, ponteiro)
 TASKDIALOGCONFIG.dwFlags: D$ 0                ; TASKDIALOG_FLAGS (4 bytes)
 TASKDIALOGCONFIG.dwCommonButtons: D$ 0        ; TASKDIALOG_COMMON_BUTTON_FLAGS (4 bytes)
 TASKDIALOGCONFIG.pszWindowTitle: D$ 0          ; LPCWSTR (4 bytes, ponteiro para string Unicode)
 TASKDIALOGCONFIG.hMainIcon: D$ 0              ; HICON (4 bytes, union com pszMainIcon)
 TASKDIALOGCONFIG.pszMainInstruction: D$ 0      ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.pszContent: D$ 0              ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.cButtons: D$ 0                ; UINT (4 bytes)
 TASKDIALOGCONFIG.pButtons: D$ 0                ; const TASKDIALOG_BUTTON* (4 bytes, ponteiro)
 TASKDIALOGCONFIG.nDefaultButton: D$ 0          ; int (4 bytes)
 TASKDIALOGCONFIG.cRadioButtons: D$ 0          ; UINT (4 bytes)
 TASKDIALOGCONFIG.pRadioButtons: D$ 0          ; const TASKDIALOG_BUTTON* (4 bytes, ponteiro)
 TASKDIALOGCONFIG.nDefaultRadioButton: D$ 0    ; int (4 bytes)
 TASKDIALOGCONFIG.pszVerificationText: D$ 0    ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.pszExpandedInformation: D$ 0  ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.pszExpandedControlText: D$ 0  ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.pszCollapsedControlText: D$ 0 ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.hFooterIcon: D$ 0            ; HICON (4 bytes, union com pszFooterIcon)
 TASKDIALOGCONFIG.pszFooter: D$ 0              ; LPCWSTR (4 bytes, ponteiro)
 TASKDIALOGCONFIG.pfCallback: D$ 0              ; PFTASKDIALOGCALLBACK (4 bytes, ponteiro para função)
 TASKDIALOGCONFIG.lpCallbackData: D$ 0          ; LONG_PTR (4 bytes em 32 bits)
 TASKDIALOGCONFIG.cxWidth: D$ 0]                ; UINT (4 bytes)

; displacements for TASKDIALOGCONFIG structure
[TASKDIALOGCONFIG.cbSizeDis 0
 TASKDIALOGCONFIG.hwndParentDis 4
 TASKDIALOGCONFIG.hInstanceDis 8
 TASKDIALOGCONFIG.dwFlagsDis 12
 TASKDIALOGCONFIG.dwCommonButtonsDis 16
 TASKDIALOGCONFIG.pszWindowTitleDis 20
 TASKDIALOGCONFIG.hMainIconDis 24
 TASKDIALOGCONFIG.pszMainInstructionDis 28
 TASKDIALOGCONFIG.pszContentDis 32
 TASKDIALOGCONFIG.cButtonsDis 36
 TASKDIALOGCONFIG.pButtonsDis 40
 TASKDIALOGCONFIG.nDefaultButtonDis 44
 TASKDIALOGCONFIG.cRadioButtonsDis 48
 TASKDIALOGCONFIG.pRadioButtonsDis 52
 TASKDIALOGCONFIG.nDefaultRadioButtonDis 56
 TASKDIALOGCONFIG.pszVerificationTextDis 60
 TASKDIALOGCONFIG.pszExpandedInformationDis 64
 TASKDIALOGCONFIG.pszExpandedControlTextDis 68
 TASKDIALOGCONFIG.pszCollapsedControlTextDis 72
 TASKDIALOGCONFIG.hFooterIconDis 76
 TASKDIALOGCONFIG.pszFooterDis 80
 TASKDIALOGCONFIG.pfCallbackDis 84
 TASKDIALOGCONFIG.lpCallbackDataDis 88
 TASKDIALOGCONFIG.cxWidthDis 92]

[Size_Of_TASKDIALOGCONFIG 96]

; Equates used by this thing (In hexadecimal)

; enum _TASKDIALOG_COMMON_BUTTON_FLAGS ; 4 bytes
[TDCBF_OK_BUTTON 01
 TDCBF_YES_BUTTON 02
 TDCBF_NO_BUTTON 04
 TDCBF_CANCEL_BUTTON 08
 TDCBF_RETRY_BUTTON 010
 TDCBF_CLOSE_BUTTON 020]

; enum _TASKDIALOG_ELEMENTS ; 4 bytes
[TDE_CONTENT 0
 TDE_EXPANDED_INFORMATION 01
 TDE_FOOTER 02
 TDE_MAIN_INSTRUCTION 03]

; enum _TASKDIALOG_FLAGS ; 4 bytes
[TDF_ENABLE_HYPERLINKS 01
 TDF_USE_HICON_MAIN 02
 TDF_USE_HICON_FOOTER 04
 TDF_ALLOW_DIALOG_CANCELLATION 08
 TDF_USE_COMMAND_LINKS 010
 TDF_USE_COMMAND_LINKS_NO_ICON 020
 TDF_EXPAND_FOOTER_AREA 040
 TDF_EXPANDED_BY_DEFAULT 080
 TDF_VERIFICATION_FLAG_CHECKED 0100
 TDF_SHOW_PROGRESS_BAR 0200
 TDF_SHOW_MARQUEE_PROGRESS_BAR 0400
 TDF_CALLBACK_TIMER 0800
 TDF_POSITION_RELATIVE_TO_WINDOW 01000
 TDF_RTL_LAYOUT 02000
 TDF_NO_DEFAULT_RADIO_BUTTON 04000
 TDF_CAN_BE_MINIMIZED 08000
 TDF_SIZE_TO_CONTENT 01000000]

; enum _TASKDIALOG_ICON_ELEMENTS ; 4 bytes
[TDIE_ICON_MAIN 0
 TDIE_ICON_FOOTER 01]

; enum _TASKDIALOG_MESSAGES ; 4 bytes
[TDM_NAVIGATE_PAGE 0465
 TDM_CLICK_BUTTON 0466
 TDM_SET_MARQUEE_PROGRESS_BAR 0467
 TDM_SET_PROGRESS_BAR_STATE 0468
 TDM_SET_PROGRESS_BAR_RANGE 0469
 TDM_SET_PROGRESS_BAR_POS 046A
 TDM_SET_PROGRESS_BAR_MARQUEE 046B
 TDM_SET_ELEMENT_TEXT 046C
 TDM_CLICK_RADIO_BUTTON 046E
 TDM_ENABLE_BUTTON 046F
 TDM_ENABLE_RADIO_BUTTON 0470
 TDM_CLICK_VERIFICATION 0471
 TDM_UPDATE_ELEMENT_TEXT 0472
 TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE 0473
 TDM_UPDATE_ICON 0474]

; enum _TASKDIALOG_NOTIFICATIONS ; 4 bytes
[TDN_CREATED 0
 TDN_NAVIGATED 01
 TDN_BUTTON_CLICKED 02
 TDN_HYPERLINK_CLICKED 03
 TDN_TIMER 04
 TDN_DESTROYED 05
 TDN_RADIO_BUTTON_CLICKED 06
 TDN_DIALOG_CONSTRUCTED 07
 TDN_VERIFICATION_CLICKED 08
 TDN_HELP 09
 TDN_EXPANDO_BUTTON_CLICKED 0A]

; enum _TASKPAGE ; 4 bytes
[TASKPAGE_TASK 0
 TASKPAGE_SCHEDULE 01
 TASKPAGE_SETTINGS 02]

; enum _TASK_ACTION_TYPE ; 4 bytes
[TASK_ACTION_EXEC 0
 TASK_ACTION_COM_HANDLER 05
 TASK_ACTION_SEND_EMAIL 06
 TASK_ACTION_SHOW_MESSAGE 07]

; enum _TASK_COMPATIBILITY ; 4 bytes
[TASK_COMPATIBILITY_AT 0
 TASK_COMPATIBILITY_V1 01
 TASK_COMPATIBILITY_V2 02
 TASK_COMPATIBILITY_V2_1 03
 TASK_COMPATIBILITY_V2_2 04
 TASK_COMPATIBILITY_V2_3 05
 TASK_COMPATIBILITY_V2_4 06]

; enum _TASK_CREATION ; 4 bytes
[TASK_VALIDATE_ONLY 01
 TASK_CREATE 02
 TASK_UPDATE 04
 TASK_CREATE_OR_UPDATE 06
 TASK_DISABLE 08
 TASK_DONT_ADD_PRINCIPAL_ACE 010
 TASK_IGNORE_REGISTRATION_TRIGGERS 020]

; enum _TASK_ENUM_FLAGS ; 4 bytes
[TASK_ENUM_HIDDEN 01]

; enum _TASK_INSTANCES_POLICY ; 4 bytes
[TASK_INSTANCES_PARALLEL 0
 TASK_INSTANCES_QUEUE 01
 TASK_INSTANCES_IGNORE_NEW 02
 TASK_INSTANCES_STOP_EXISTING 03]

; enum _TASK_LOGON_TYPE ; 4 bytes
[TASK_LOGON_NONE 0
 TASK_LOGON_PASSWORD 01
 TASK_LOGON_S4U 02
 TASK_LOGON_INTERACTIVE_TOKEN 03
 TASK_LOGON_GROUP 04
 TASK_LOGON_SERVICE_ACCOUNT 05
 TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD 06]

; enum _TASK_PROCESSTOKENSID ; 4 bytes
[TASK_PROCESSTOKENSID_NONE 0
 TASK_PROCESSTOKENSID_UNRESTRICTED 01
 TASK_PROCESSTOKENSID_DEFAULT 02]

; enum _TASK_RUNLEVEL ; 4 bytes
[TASK_RUNLEVEL_LUA 0
 TASK_RUNLEVEL_HIGHEST 01]

; enum _TASK_RUN_FLAGS ; 4 bytes
[TASK_RUN_NO_FLAGS 0
 TASK_RUN_AS_SELF 01
 TASK_RUN_IGNORE_CONSTRAINTS 02
 TASK_RUN_USE_SESSION_ID 04
 TASK_RUN_USER_SID 08]

; enum _TASK_SESSION_STATE_CHANGE_TYPE ; 4 bytes
[TASK_CONSOLE_CONNECT 01
 TASK_CONSOLE_DISCONNECT 02
 TASK_REMOTE_CONNECT 03
 TASK_REMOTE_DISCONNECT 04
 TASK_SESSION_LOCK 07
 TASK_SESSION_UNLOCK 08]

; enum _TASK_STATE ; 4 bytes
[TASK_STATE_UNKNOWN 0
 TASK_STATE_DISABLED 01
 TASK_STATE_QUEUED 02
 TASK_STATE_READY 03
 TASK_STATE_RUNNING 04]

[TD_WARNING_ICON 0FFFF
 TD_ERROR_ICON 0FFFE
 TD_INFORMATION_ICON 0FFFD
 TD_SHIELD_ICON 0FFFC]

; TASKDIALOG_BUTTON structure

[TASKDIALOG_BUTTON:
 TASKDIALOG_BUTTON.nButtonID: D$ &IDOK
 TASKDIALOG_BUTTON.pszButtonText: D$ Sz_ChangePassword]

; Variables to make this stuff works !

[Sz_ChangePassword: U$ "Change password", 0] ; Unicode String
[Sz_ChangePassword2: U$ "Change Password", 0] ; Unicode String
[Sz_Text: U$ "Remember your changed password.", 0] ; Unicode String

[hInstance: D$ 0]
[nButtonPressed: D$ 0]
[hDll: D$ 0]
[hTaskDialogIndirect: D$ 0]


And the code (Tks, Timo), to make this work. Now without manifest.

Main:
    call 'KERNEL32.GetModuleHandleA' &NULL
    mov D$hInstance eax
    call 'KERNEL32.LoadLibraryA' {"C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\COMCTL32.dll", 0}
    mov D$hDll eax
    call 'kernel32.GetProcAddress' eax, {B$ "TaskDialogIndirect", 0}
    mov D$hTaskDialogIndirect eax

    mov D$nButtonPressed 0
    mov eax D$hInstance | mov D$TASKDIALOGCONFIG.hInstance eax
    mov D$TASKDIALOGCONFIG.dwCommonButtons TDCBF_CANCEL_BUTTON
    mov D$TASKDIALOGCONFIG.hMainIcon TD_WARNING_ICON
    mov D$TASKDIALOGCONFIG.pszMainInstruction Sz_ChangePassword2
    mov D$TASKDIALOGCONFIG.pszContent Sz_Text
    mov D$TASKDIALOGCONFIG.pButtons TASKDIALOG_BUTTON
    mov D$TASKDIALOGCONFIG.cButtons 1
    call D$hTaskDialogIndirect TASKDIALOGCONFIG, nButtonPressed, 0, 0
    call 'KERNEL32.ExitProcess' 0

The equates can also be found with wine at:
https://github.com/wine-mirror/wine/blob/master/include/commctrl.h#L5541


And one more examples on how to use this stuff (Sorry, found it in russian, so far - http://www.pmbk.ru/lister/055/4/index.shtml )
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Some more tests based on the VB link provided earlier



Main:
    call 'KERNEL32.GetModuleHandleA' &NULL
    mov D$hInstance eax
    call 'KERNEL32.LoadLibraryA' {"C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\COMCTL32.dll", 0}
    mov D$hDll eax
    call 'kernel32.GetProcAddress' eax, {B$ "TaskDialogIndirect", 0}
    mov D$hTaskDialogIndirect eax

    mov D$nButtonPressed 0
    mov eax D$hInstance | mov D$TASKDIALOGCONFIG.hInstance eax
    mov D$TASKDIALOGCONFIG.dwCommonButtons (TDCBF_YES_BUTTON+TDCBF_NO_BUTTON)
    mov D$TASKDIALOGCONFIG.hMainIcon TD_SHIELD_ICON
    mov D$TASKDIALOGCONFIG.pszMainInstruction {U$ "You're about to do something stupid.", 0};Sz_ChangePassword2
    mov D$TASKDIALOGCONFIG.pszContent {U$ "Are you absolutely sure you want to continue with this really bad idea?", 0}
    mov D$TASKDIALOGCONFIG.pButtons TASKDIALOG_BUTTON
    mov D$TASKDIALOGCONFIG.cButtons 1
    mov D$TASKDIALOGCONFIG.pszWindowTitle {U$ "cTaskDialog Project", 0}
    call D$hTaskDialogIndirect TASKDIALOGCONFIG, nButtonPressed, 0, 0


    call 'KERNEL32.ExitProcess' 0

Next, is similar as above



[TASKDIALOG_RADIO_BUTTON:
 TASKDIALOG_RADIO_BUTTON1.nButtonID: D$ 110
 TASKDIALOG_RADIO_BUTTON1.pszButtonText: D$ Sz_Radio1

 TASKDIALOG_RADIO_BUTTON2.nButtonID: D$ 111
 TASKDIALOG_RADIO_BUTTON2.pszButtonText: D$ Sz_Radio2

 TASKDIALOG_RADIO_BUTTON3.nButtonID: D$ 112
 TASKDIALOG_RADIO_BUTTON3.pszButtonText: D$ Sz_Radio3]

[Sz_Radio1: U$ "Let´s do Item1", 0] ; Unicode String
[Sz_Radio2: U$ "Or maybe 2", 0] ; Unicode String
[Sz_Radio3: U$ "Super secret option", 0] ; Unicode String

Main:
    call 'KERNEL32.GetModuleHandleA' &NULL
    mov D$hInstance eax
    call 'KERNEL32.LoadLibraryA' {"C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\COMCTL32.dll", 0}
    mov D$hDll eax
    call 'kernel32.GetProcAddress' eax, {B$ "TaskDialogIndirect", 0}
    mov D$hTaskDialogIndirect eax
    mov D$TASKDIALOGCONFIG.dwCommonButtons (TDCBF_YES_BUTTON+TDCBF_NO_BUTTON)
    mov D$TASKDIALOGCONFIG.hMainIcon TD_SHIELD_ICON
    mov D$TASKDIALOGCONFIG.pszMainInstruction {U$ "You're about to do something stupid.", 0};Sz_ChangePassword2
    mov D$TASKDIALOGCONFIG.pszContent {U$ "Are you absolutely sure you want to continue with this really bad idea?", 0}
    mov D$TASKDIALOGCONFIG.pRadioButtons TASKDIALOG_RADIO_BUTTON
    mov D$TASKDIALOGCONFIG.cRadioButtons 3
    mov D$TASKDIALOGCONFIG.pszWindowTitle {U$ "cTaskDialog Project", 0}
    call D$hTaskDialogIndirect TASKDIALOGCONFIG, nButtonPressed, 0, 0

    call 'KERNEL32.ExitProcess' 0





Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

NoCforMe

Not worth all the damn trouble, I'd say.
Assembly language programming should be fun. That's why I do it.

guga

Quote from: NoCforMe on April 10, 2025, 05:58:26 PMNot worth all the damn trouble, I'd say.

Couldn´t agree more. It´s out of my mind why M$ do such things.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

sinsi

Quote from: guga on April 10, 2025, 06:12:57 PM
Quote from: NoCforMe on April 10, 2025, 05:58:26 PMNot worth all the damn trouble, I'd say.

Couldn´t agree more. It´s out of my mind why M$ do such things.
I'm sure it's all a part of Microsoft's One UI To Rule Them AllTM

TimoVJL

#21
Now testing a small include-file for TaskDialog.
Test program using ml.64 isn't ready, perhaps never, but working code for poasm is under tests.
;TestTaskDialog2.asm
option dotname
option casemap:none

include TaskDialogMS.inc
includelib kernel32.lib
includelib comctl32.lib

tp_ExitProcess typedef proto :dword
externdef __imp_ExitProcess : ptr tp_ExitProcess
ExitProcess equ <__imp_ExitProcess>

tp_GetModuleHandle typedef proto :qword
externdef __imp_GetModuleHandleA : ptr tp_GetModuleHandle
GetModuleHandle equ <__imp_GetModuleHandleA>

tp_TaskDialogIndirect typedef proto :qword, :qword, :qword, :qword
externdef __imp_TaskDialogIndirect : ptr tp_TaskDialogIndirect
TaskDialogIndirec equ <__imp_TaskDialogIndirect>

.drectve SEGMENT
;db "-largeaddressaware:no "
db "-manifest:embed -manifestdependency:""type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"""
;db "-manifestdependency:""type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"""
.drectve ENDS

.data
hInst qword ?
sText1 dw 'T','e','s','t',0
sContent dw 'T','e','s','t',0
tdc TASKDIALOGCONFIG <sizeof TASKDIALOGCONFIG,0,0,0,TDCBF_CANCEL_BUTTON,0,<TD_WARNING_ICON>,sText1,sContent>


.code

mainCRTStartup proc
sub rsp, 28h
;invoke GetModuleHandle, 0
xor ecx, ecx
call GetModuleHandle
mov hInst, rax
lea rcx, tdc
mov tdc.hInstance, rax
;mov tdc.dwCommonButtons, TDCBF_CANCEL_BUTTON
;mov tdc.pszMainIcon.u1, TD_WARNING_ICON
;mov tdc.pszMainInstruction, offset sText1
;mov tdc.pszContent, offset sContent
;invoke TaskDialogIndirec, addr tdc, 0, 0, 0
xor r9d, r9d
xor r8d, r8d
xor ecx, ecx
lea rcx, tdc
;invoke ExitProcess, 0
xor ecx, ecx
call ExitProcess
mainCRTStartup endp
end
EDIT: add missing option casemap:none
May the source be with you

NoCforMe

OK, enough with the stupid "task dialog" stuff; what the hell does "task dialog" mean, anyhow?

Here's my homebrew version for you to check out.
It creates a custom dialog, so I'm calling it a "custom dialog creator".
The creation module contains a subroutine to create an in-memory dialog template from a set of simple structures, CreateCustomDialog(). It also has the dialog procedure you use to deploy the dialog, CustomDialogProc().

Much, much simpler than the Micro$oft abomination. Here's how you set up a dialog (the one in the attached testbed):

CustomDialogParms $CD_info <DialogTitle, DialogItemList, 9, NULL, $dlgFontSize, "Segoe UI">

DialogItemList LABEL $CD_item
  $CD_item <$CD_static1, Static1Text>
  $CD_item <$CD_static2, Static2Text>
  $CD_item <$CD_check, Radio1Text>
  $CD_item <$CD_check, Radio2Text>
  $CD_item <$CD_check, Radio3Text>
  $CD_item <$CD_buttonOK, OKtext>
  $CD_item <$CD_buttonCancel, CancelText>
  $CD_item <$CD_button3, Btn3Text>
  $CD_item <$CD_button4, Btn4Text>
plus the associated strings referred to there. (See the source.)

This creates a dialog with two static text fields, three checkboxes and four buttons, the first two of which are the familiar "OK" and "Cancel".

You can play around with this and create your own dialog (within limits).

This is only a proof-of-concept thing. The available controls are:
  • Two static controls, one a larger one at the top for a big block of text, the second one a single line that displays text in a larger and bolder font
  • One to three checkboxes
  • One to three radio buttons
  • Up to 4 buttons at the bottom

You can have either the radio buttons or the checkboxes, but not both, as they are created in the same location. (You could change this, of course, to accomodate both of these.)

Lots more stuff you could do with this: display a small bitmap image or icon; put in an edit field, etc.

Those other 2 buttons: not really sure what you would want to do with them. It's set up now so that either OK or Cancel closes the dialog, with OK returning the state of controls. (The results are returned in a $CD_results structure showing the state of all possible settable controls.) So the other 2 buttons are kind of orphaned. I guess you could figure out some kind of hook scheme to transfer control to a custom procedure, but that seems kind of ugly.

Like to hear any ideas of where this could go from here. I think it's a potentially useful thing, more flexible than a MessageBox.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Now with an icon!

You cannot view this attachment.

All you gotta add is
IconFilename DB "Dice.ico", 0

  $CD_item <$CD_icon, IconFilename>
Assembly language programming should be fun. That's why I do it.

guga

Opened it in Radasm and this is the error i´ve got.

C:\Masm32\Bin\ML.EXE /c /coff /Cp /nologo /I"C:\Masm32\Include" "C:\masm32\examples\David\CreateCustomDialog\CreateCustomDialogTest.asm"
 Assembling: C:\masm32\examples\David\CreateCustomDialog\CreateCustomDialogTest.asm

***********
ASCII build
***********

C:\Masm32\Bin\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"C:\Masm32\Lib" "C:\masm32\examples\David\CreateCustomDialog\CreateCustomDialogTest.obj"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

CreateCustomDialogTest.obj : error LNK2001: unresolved external symbol _CustomDialogProc@16
CreateCustomDialogTest.obj : error LNK2001: unresolved external symbol _CreateCustomDialog@4
CreateCustomDialogTest.exe : fatal error LNK1120: 2 unresolved externals

Make error(s) occured.
Total compile time 516 ms
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

NoCforMe

Did you use the "makefile" I included, or copy it correctly?
@echo off

ml /c /coff /Fl /Sn CreateCustomDialog.asm
if errorlevel 1 goto errasm

ml /c /coff /Fl /Sn CreateCustomDialogTest.asm
if errorlevel 1 goto errasm

link /SUBSYSTEM:WINDOWS CreateCustomDialogTest CreateCustomDialog VisualStyles
if errorlevel 1 goto errlink

goto TheEnd

:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error

:TheEnd

Works fine here.
I'm using link.exe version 5.12.8078
Assembly language programming should be fun. That's why I do it.

guga

Both

I tried to simplyy click upon the makefile and nothing happened. Then, i tried to open the file in Radasm and this was the erropr it showed to me. I didn´t created another project in Radasm, i opened the file as asm, and tried to compile it directly. I tried to find where include the "includes" in Radasm properties (or something), but couldnt find.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Found the error when i clicked on the batch file. I now opened a command prompt, to see why it was not assembling

"Microsoft Windows [versão 10.0.19045.5737]
(c) Microsoft Corporation. Todos os direitos reservados.

C:\Users\Usuario>cd\

C:\>cd masm32

C:\masm32>cd examples

C:\masm32\examples>cd David

C:\masm32\examples\David>cd CreateCustomDialog

C:\masm32\examples\David\CreateCustomDialog>makeccdtest.bat
'ml' não é reconhecido como um comando interno
ou externo, um programa operável ou um arquivo em lotes.
_
Assembly Error
C:\masm32\examples\David\CreateCustomDialog>
"

It´s not finding the ml.exe. But still, can´t assemble it.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

zedd151

Quote from: NoCforMe on April 16, 2025, 11:09:14 AMWorks fine here.
I'm using link.exe version 5.12.8078

Works fine here using ml&link from the masm32 SDK, after restoring the bin path in the batch file: "\masm32\bin\ml..."; \masm32\bin\link..."  :rolleyes:
I didn't feel like adding the dice icon. I have been doing enough "rolling of the dice here lately"  :skrewy:



guga if you know where ml and link are, just adjust the batch file.  :smiley:
You shouldn't have to CD all over the place.

guga

Great. Now it worked from the batch

@echo off

\masm32\bin\ml /c /coff /Fl /Sn CreateCustomDialog.asm
:ml /c /coff /Fl /Sn /Zi CreateCustomDialog.asm
if errorlevel 1 goto errasm

\masm32\bin\ml /c /coff /Fl /Sn CreateCustomDialogTest.asm
:ml /c /coff /Fl /Sn /Zi CreateCustomDialogTest.asm
if errorlevel 1 goto errasm

\masm32\bin\link /SUBSYSTEM:WINDOWS CreateCustomDialogTest CreateCustomDialog VisualStyles
:link /SUBSYSTEM:WINDOWS /debug CreateCustomDialogTest CreateCustomDialog VisualStyles
if errorlevel 1 goto errlink

dir CreateCustomDialog.*
goto TheEnd

:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error

:TheEnd

How to make it also work with Radasm ?



Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com