cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
rguggisberg
Level 13

Bring MessageBox to Front

Is there a way to force a MessageBox to the front? I have some that get hidden behind other windows. How do you avoid that?
Thanks
Labels (1)
0 Kudos
(15) Replies
Alpesh
Flexera Alumni

Hi,

Is it a MSI project? If yes, then instead of using InstallScript's MessageBox function, try using the MsiProcessMessage function -> http://msdn.microsoft.com/en-us/library/aa370354(v=vs.85).aspx.

Thanks!
0 Kudos
rguggisberg
Level 13

Thanks. Seems like a lot of trouble for something so simple.
Yes, I am using a Basic MSI project. Is there no other way?
0 Kudos
Videstra
Level 7

Is this happening on Windows 7? This appears to be a known problem with InstallShield and Windows 7. I'm not sure how you would address the messagebox issue but when writing a .net managed DLL it is a real problem for any dialogs that are created.

http://community.flexerasoftware.com/showthread.php?t=195659

If your vbs messagebox will not come forward then I suspect you will have to time it better in your installation so that nothing else in your installation is showing at the time - or hope Flexera addresses this EXTREMELY annoying problem in a patch soon.


Des
0 Kudos
Alpesh
Flexera Alumni

rguggisberg,

You can still use the InstallScript custom action, but instead of using MessageBox function, use MsiProcessMessage.

I believe you are seeing this problem during silent uninstall or uninstall from ARP. Basically in these situations, there is no Msi window available and hence, no handle can be passed to the MessageBox call. Using MsiProcessMessage will overcome this issue.

I hope this helps.

Thanks!
0 Kudos

Hi Alpesh,

Facing same issue during uninstall in UI mode from Control Panel, the prompt created by messageboxEx is hiding behind the progress bar of uninstall window.

Below is the code of installscript:

NUMBER svSize;
NUMBER nResult;
BOOL MessageBoxResult;
HWND hSettingsWnd;
function Wizard(hMSI)
STRING ivValue[1024], sgProductPathSE;
STRING svMessage, svTitle;
begin
svSize = 4096;
sgProductPathSE = ivValue ^ "Program" ^ "ABC.exe";
// Wait for 10 seconds
Sleep(10000);
// Find the "MessageBoxResult" window (Which is yet to be created by below syntax)and bring it to the foreground
hSettingsWnd = FindWindow("#32770", @ID_STRING5 + " " + @ID_STRING6);
SetForegroundWindow(hSettingsWnd);
// Display the message box
MessageBoxResult = MessageBoxEx(@ID_STRING2 + L"\n\n" + @ID_STRING3, @ID_STRING5 + " " + @ID_STRING6, MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL | SetForegroundWindow(hSettingsWnd) );

// Launch the abc.exe application if the user clicked "Yes"
if (IDYES == MessageBoxResult)then
LaunchAppAndWait(sgProductPathSE, "", WAIT);
endif;
end;

Can you kindly help me to force a MessageBoxResult to prompted on top of uninstall progressbar?

0 Kudos
varul
Revenera Moderator Revenera Moderator
Revenera Moderator

Hi @ShubhamK

 Could you please try using msiprocessmessage option show the message box. please check below help link.

https://learn.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiprocessmessage

function MyFunction(hMSI)
// To Do: Declare local variables.
NUMBER TEST;
NUMBER hRecord;
begin
hRecord = MsiCreateRecord(1);
MsiRecordSetString(hRecord,1,"TEST STRING");
//MsiRecordSetString();
TEST = MsiProcessMessage(hMSI, INSTALLMESSAGE_USER|MB_YESNO, hRecord);
if (TEST = IDYES) then
MessageBox("YES",INFORMATION);
endif;

if (TEST = IDNO ) then
MessageBox("NO",INFORMATION);
endif;

Thank You @varul , I'm able to popup the dialog on top of the uninstall progress bar.
One more question, is there any way to provide title to the  MsiProcessMessage prompt.

I again appreciate for your quick help.
Thanks

0 Kudos

@varul , MessageBox is getting popup on Normal monitor,
But however on 4k monitor message is getting cropped. Do we have any way for 4k monitor issue?

0 Kudos
rguggisberg
Level 13

Thanks Alpesh. I am not able to make MsiProcessMessage work. Not sure it would be any better anyway. The problem happens on install when the user activates other windows while waiting for the install to reach this point. In that case the MessageBox is behind more recently activated windows and there is no flashing icon on the task bar, so there is no indication that the install is waiting for a reply. My problem in the code below seems to be that MsiFormatRecord is returning the error ERROR_MORE_DATA and I don't know why. But even getting past that... I am not sure that this window would be forced to the top in the scenario described.
Thanks.

HWND hRec;
NUMBER nResult;
STRING szOutput[1000];
LONG lCount;
begin
.
.
.
MessageBox (xxx is not installed. You must install it from the Tech Support CD.", WARNING); // Message box may be hidden behind other more recently active windows
hRec = MsiCreateRecord(1);
nResult = MsiRecordSetString(hRec, 1, szMessage);
nResult = MsiRecordSetString(hRec, 0, "[1]");
lCount = StrLength(szMessage);
nResult = MsiFormatRecord(hMSI, hRec, szOutput, lCount);
// At this point nResult=ERROR_MORE_DATA
nResult = MsiProcessMessage(hMSI,INSTALLMESSAGE_INFO, hRec);
// At this point nResult=1
0 Kudos
foerdi
Level 4

WINAPI MessageBox?

Then (hWnd)parent should be the MSI dialog

In C++

if (NULL == (hWndParent=::FindWindow(_T("MsiDialogCloseClass"), _T("")))) // full UI
{
if (NULL == (hWndParent=::FindWindow(_T("#32770"), _T("")))) // basic UI
{
LOGERR(_T("FindWindow failed, error ") << GetLastError()); // silent?
return ERROR_INSTALL_FAILURE;
}
}
0 Kudos
foerdi
Level 4

Or you try it without parent window and use MB_SYSTEMMODAL instead
0 Kudos
rguggisberg
Level 13

foerdi,
Thanks for the clue. I tried using the line below in an InstallScript CA.
MessageBox ("My Message", WARNING|Value);
I substituted various values from
http://www.aspfree.com/c/a/VB.NET/Mastering-the-Message-Box/3/
for Value. Most notably I expected to be able to make this work with MB_SETFOREGROUND (0x00010000) but no such luck. I would think something like this could be made to work but I am not getting it. If anyone else has the answer please reply.
Thanks.
0 Kudos
foerdi
Level 4

Can you please describe again what the exact behaviour is?
Is the messagebox behind the installation or is it application modal, but the more recent windows are over installation(and messagebox)? the system modal flag didn't help?

BTW InstallScript MessageBox calls WINAPI MessageBox, BUT it automatically gives the correct hWnd of the Installation, and I remember there were some issues with mixing IS constants and MS constants in the flags.

Have you also tried to call the (user32.dll) MessageBoxA with the wrapper (Custom Actions->New Standard DLL->Located in search path)?

BTW Please use the values, not the constant names.

I would recommend to put all your logic, all your CAs either in C++(CA native dll) or C# (DTF/WiX). You can debug then such confusing buggy scenarios with MsiBreak and MMsiBreak.
0 Kudos
rguggisberg
Level 13

Thanks foerdi.
This would not be a problem if we could just do like others and say "Close all other windows". It is really only a problem when the user is navigating through other windows while waiting. The message box then appears behind other windows and there is not even a flashing icon in the task bar.

I have message boxes in other CAs that are 'Deferred Execution In System Context' and they will always pop out to the front. This one is in a CA that is marked for "Immediate Execution'.

The system modal flag didn't help.
I did not mix IS constants and MS constants in the flags.

I have not tried to call the (user32.dll) MessageBoxA with the wrapper (Custom Actions->New Standard DLL->Located in search path) as you suggested.

Thanks Again.
0 Kudos
manomatt
Level 8

Following code in installscript will display a message box on top, while uninstalling from add/remove program


hRecord = MsiCreateRecord(1);
MsiRecordSetString( hRecord, 0, "Please uninstall Previous msi...");
MsiProcessMessage(hInst, INSTALLMESSAGE_ERROR, hRecord);
MsiCloseHandle(hRecord);
0 Kudos