summaryrefslogtreecommitdiffstats
path: root/packaging/win32/macros/SHMessageBoxCheck.nsh
blob: 502923bf2b074a213900a6231be2aeddd185db22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# SHMessageBoxCheck
#   Works like MessageBox but includes a checkbox that gives the user the option not to show the message box again.
#   In that case the return value (first value on the stack) is always set to the last user choice
#
# See
#   http://nsis.sourceforge.net/SHMessageBoxCheck   (documentation)
#   https://msdn.microsoft.com/library/windows/desktop/bb773836.aspx   (implementation details)
#

# types to indicate the buttons displayed in the message box
!define MB_OK                0x00000000
!define MB_OKCANCEL          0x00000001
!define MB_ABORTRETRYIGNORE  0x00000002 # not officially supported, use at your own risk!
!define MB_YESNOCANCEL       0x00000003 # not officially supported, use at your own risk!
!define MB_YESNO             0x00000004
!define MB_RETRYCANCEL       0x00000005 # not officially supported, use at your own risk!
!define MB_CANCELTRYCONTINUE 0x00000006 # not officially supported, use at your own risk!
!define MB_HELP              0x00004000 # not officially supported, use at your own risk!

# types to display an icon in the message box
!define MB_ICONHAND          0x00000010
!define MB_ICONQUESTION      0x00000020 # MS bug: Same as MB_ICONEXCLAMATION
!define MB_ICONEXCLAMATION   0x00000030
!define MB_ICONINFORMATION   0x00000040


# return values
!define IDOK        1
!define IDCANCEL    2
!define IDABORT     3
!define IDRETRY     4
!define IDIGNORE    5
!define IDYES       6
!define IDNO        7
!define IDCONTINUE 11
!define IDTRYAGAIN 10



# the user's previous choice (i.e. the button clicked in the message box)
Var _lastReturnValue

# The value that the call to SHMessageBoxCheck should return when the user chose not to display the message box again
!define _DEFAULT 9999

# Windows XP does not expose the function name, so we have to specify the function by ordinal value
!ifdef NSIS_UNICODE
    !define _SHMessageBoxCheck_Ordinal 191
!else
    !define _SHMessageBoxCheck_Ordinal 185
!endif



!macro SHMessageBoxCheckInit _UNIQUE_STRING
    # SHMessageBoxCheck stores the user's choice not to display the message box again in the registry, see
    #   HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain
    !ifdef _PSZ_REG_VAL
        !error "Only call SHMessageBoxCheckInit once and make sure to call SHMessageBoxCheckCleanup before using it again"
    !else
        # the unique string used to identify this message (and name of the registry value used to store the checkbox status)
        !define _PSZ_REG_VAL ${_UNIQUE_STRING}
    !endif

    # make sure the registry value is not yet set (for whatever reason)
    ${SHMessageBoxCheckCleanup}
!macroend
!define SHMessageBoxCheckInit "!insertmacro SHMessageBoxCheckInit"


!macro SHMessageBoxCheckCleanup
    # delete the registry key that is used to store the checkbox status so we can start fresh next time
    DeleteRegValue HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain" "${_PSZ_REG_VAL}"
!macroend
!define SHMessageBoxCheckCleanup "!insertmacro SHMessageBoxCheckCleanup"


!macro SHMessageBoxCheck _CAPTION _TEXT _TYPE
    # this would be the simple way (by name)
    # System::Call "shlwapi::SHMessageBoxCheck(p $HWNDPARENT, t '${_TEXT}', t '${_CAPTION}', i ${_TYPE}, i ${_DEFAULT}, t '${_PSZ_REG_VAL}') i .r0"

    # for backwards-compatibility we get the process address by specifying the function's ordinal value
    System::Call "kernel32::GetModuleHandle(t 'shlwapi.dll') p .s"
    System::Call "kernel32::GetProcAddress(p s, i ${_SHMessageBoxCheck_Ordinal}) p .r0"
    System::Call "::$0(p $HWNDPARENT, t '${_TEXT}', t '${_CAPTION}', i ${_TYPE}, i ${_DEFAULT}, t '${_PSZ_REG_VAL}') i .r0"

    # save the user's choice (unless the default value was returned - then don't update and return the saved choice)
    StrCmp $0 ${_DEFAULT} +2 0
        StrCpy $_lastReturnValue $0

    # push the return value to the stack
    Push $_lastReturnValue
!macroend
!define SHMessageBoxCheck "!insertmacro SHMessageBoxCheck"