Reputation: 999
The problem occurs when the hWndParent
is positioned near the taskbar at the base of the screen. Clicking pszExpandedInformation
extends the TaskDialog form below offscreen instead of moving the newly sized form up screen to show the expanded details.
The TASKDIALOGCONFIG structure is filled for 64bit in the following test code accordingly, click "See Details" to submerge:
Gui, testGui: New, -MaximizeBox -MinimizeBox +OwnDialogs +LastFound
testGuiW := floor(A_ScreenWidth/6)
testGuiH := floor(A_ScreenHeight/9)
Gui, testGui: Add, Button, center Default w%testGuiW% h%testGuiH% gRunTaskDialog vTaskDlg, Run TaskDialog
Gui, testGui: Default
GuiControl, testGui: Move, TaskDlg, x%testGuiW% y%testGuiH%
testGuiW := floor(A_ScreenWidth/2)
testGuiH := floor(A_ScreenHeight/3)
Gui, testGui: Show, % "y" . A_ScreenHeight - testGuiH . " w" . testGuiW . " h" . testGuiH
Return
RunTaskDialog:
retVal := TaskDialog("Test", "Test Issue", "", "Lorem ipsum dolor sit amet,`nconsectetur adipiscing elit,`nsed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.`nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,`nsunt in culpa qui officia deserunt mollit anim id est laborum.", , "Close Test")
Return
Esc::
testGuiGuiClose:
ExitApp
; Task dialog
TaskDialog(pageTitle := "Page Title", instructionTitle := "Description of issue", description := "Choose one of the following options:", expandedText := "More Information with a <A HREF=""http://www.some_link.com"">Link</a>", checkText := "Do not show this again", choice1 := "", choice2 := "", choice3 := "", choice4 := "")
{
; This function requires A_Unicode and Vista or later.
Static FooterText := ""
; Error Flags
Static S_OK = 0x0, E_OUTOFMEMORY = 0x8007000E, E_INVALIDARG = 0x80070057, E_FAIL = 0x80004005, E_ACCESSDENIED = 0x80070005
;General Flags
Static flags = 0x1011, TDF_VERIFICATION_FLAG_CHECKED = 0x0100, TDF_CALLBACK_TIMER := 0X0800
; 0x1 : TDF_ENABLE_HYPERLINKS
; 0X0010: TDF_USE_COMMAND_LINKS
; 0x1000: TDF_POSITION_RELATIVE_TO_WINDOW
; 0x1000000: TDF_SIZE_TO_CONTENT
CustomButtons := []
hwndParent := WinExist("A")
if (!(TDCallback := RegisterCallback("TDCallback", "Fast")))
{
MsgBox, 8208, Task Dialog, Could not Register Callback for the Task dialog.
return 0
}
While (tp := choice%A_Index%)
CustomButtons.Push(100 + A_Index, tp)
cButtons := CustomButtons.Length()/2
VarSetCapacity(pButtons, 4 * cButtons + A_PtrSize * cButtons, 0)
loop %cButtons%
{
iButtonID := CustomButtons[2 * A_Index -1]
iButtonText := &(b%A_Index% := CustomButtons[2 * A_Index])
NumPut(iButtonID, pButtons, (4 + A_PtrSize) * (A_Index - 1), "Int")
NumPut(iButtonText, pButtons, (4 + A_PtrSize) * A_Index - A_PtrSize, "Ptr")
}
; TASKDIALOGCONFIG structure
if (A_PtrSize == 8) ; X64
{
NumPut(VarSetCapacity(TDC, 160, 0), TDC, 0, "UInt") ; cbSize
NumPut(hwndParent, TDC, 4, "Ptr") ; hwndParent
; HINSTANCE
NumPut(flags, TDC, 20, "Int") ; dwflags
NumPut(&pageTitle, TDC, 28, "Ptr") ; pszWindowTitle
NumPut(&instructionTitle, TDC, 44, "Ptr") ; pszMainInstruction
NumPut(&description, TDC, 52, "Ptr") ; pszContent
NumPut(cButtons, TDC, 60, "UInt") ; cButtons
NumPut(&pButtons, TDC, 64, "Ptr") ; pButtons
NumPut(&checkText, TDC, 92, "Ptr") ; pszVerificationText
NumPut(&ExpandedText, TDC, 100, "Ptr") ; pszExpandedInformation
NumPut(&FooterText, TDC, 132, "Ptr") ; pszFooter
NumPut(TDCallback, TDC, 140, "Ptr") ; pfCallback
}
else
return
retVal := DllCall("Comctl32.dll\TaskDialogIndirect", "Ptr", &TDC
, "Int*", Button := 0
, "Int*", Radio := 0
, "Int*", Checked := 0)
; various error checks omitted for brevity
return retVal
}
TDCallback(hWnd, Notification, wParam, lParam, RefData)
{
Static TDE_FOOTER = 0X0002, TDM_UPDATE_ELEMENT_TEXT := 0x400 + 114, TDM_CLICK_BUTTON := 0x400 + 102, timeOut := 10
switch (Notification)
{
Case 3:
{
url := StrGet(lParam, "UTF-16") ; <A HREF="URL">Link</A>
Run %url%
}
Default:
}
}
Is there any way to reposition the form so that the lower y co-ordinates before and after expanding remain the same?
Upvotes: 0
Views: 101
Reputation: 999
The controls of the TaskDialog (apart from the Continue
button) aren't easily accessible. The other controls identify as directuihwnd and their click events aren't available other than through the callback. In this case it's TDM_UPDATE_ELEMENT_TEXT, even so, we have no control over the (changing the) dimensions of the Taskdialog.
Thus the obvious solution is to not specify the hwndParent
in the TDC
structure whenever the expando button is used, which consequently repositions the TaskDialog in the centre of the screen.
Also, the docs state:
The parent window should not be hidden or disabled when this function is called
Instead, a transient cloaked window as a parent situated somewhere above the original parent as a test candidate?
Edit: According to @Remy Lebeau's post at this forum it's possible with a hook on the TDN_DIALOG_CONSTRUCTED message to obtain the handle of the dialog, thereby facilitating the move of the form on the wParam
of TDM_UPDATE_ELEMENT_TEXT
. The windows event hook might be better for this- there is an implementation here for it.
Edit2: Turns out the window can be moved to some specified co-ordinate, unfortunately for the bottom edges to match, the precise ordinate cannot be determined until expando clicked. An estimate of the height can be determined by the number of lines in the expanded text, presumably the font is MS Sans Serif but the size could vary according to various system settings. For the example in the question, replace the callback function with the following to move the dialog up by its height factor:
TDCallback(hWnd, Notification, wParam, lParam, RefData)
{
Static tdYpos := 0, tdHeight
Static TDN_CREATED := 0, TDN_HYPERLINK_CLICKED := 3, TDN_EXPANDO_BUTTON_CLICKED := 10
switch (Notification)
{
Case TDN_CREATED:
{
VarSetCapacity(rect, 16, 0)
if (DllCall("GetWindowRect", "Ptr", hWnd, "Ptr", &rect))
tdYpos := NumGet(rect, 4, "int")
tdHeight := NumGet(rect, 12, "int") - tdYpos
VarSetCapacity(rect, 0)
}
Case TDN_HYPERLINK_CLICKED:
{
url := StrGet(lParam, "UTF-16") ; <A HREF="URL">Link</A>
Run %url%
}
Case TDN_EXPANDO_BUTTON_CLICKED:
winmove ahk_id %hWnd%, , , % (wParam?A_ScreenHeight - 2*tdHeight: tdYpos)
Default:
}
}
Edit3: A move of the dialog with improved precision is posted at this thread.
Upvotes: 0