Bot Framework Dialog Leakage Issue - botframework

I've developed a bot that calls a prompt dialog based menu at the beginning of the conversation.
Dialog call used on the Message Controller:
await Conversation.SendAsync(activity, () => new Dialogs.CustomBellaHelp());
The problem is when I execute it over the Bot Emulator prompt dialog options are properly addressed by the code.
However, when I execute it over Direct Channel prompt dialog options "leak" from the dialog code and move to the Root dialog which invokes LUIS to manage the menu options.
Thoughts on how to avoid that?
Thx!

I think you may be misunderstanding the purpose of Conversation.SendAsync(). The MakeRoot delegate isn't a function to navigate to whatever dialog you want. It's only called at the start of the conversation and it's used to create the conversation's root dialog. If a conversation is already underway, Conversation.SendAsync() sends the activity to whatever dialog is on top of the stack and the MakeRoot delegate is ignored. You can read more about dialogs and conversation flow here: https://learn.microsoft.com/en-us/azure/bot-service/bot-service-design-conversation-flow?view=azure-bot-service-3.0
If you want to start a dialog in the middle of a conversation you should do it from within another dialog and not from your messages controller. A typical way of doing this is to use context.Forward(): https://learn.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-manage-conversation-flow?view=azure-bot-service-3.0#invoke-the-new-order-dialog
As far as why Direct Line behaves differently from the emulator, you have to understand that events like conversationUpdate are channel-specific and may behave in unexpected ways on different channels.

Related

How to handle outlook new message windows notification from Outlook Add-in

I have an Outloook Add-in that implements a kind of client-server communication with a background process. I have a custom window which is filled in with some information and then it is passed in to a background process (using System.Net.HttpClient.PostAsync) which processes it.
After background process finishes processing that information, it informs to Outlook Add-in about that, then Outlook Add-in handle this, creates a new Outlook email that appears as a new message in the Outlook inbox and finally shows a windows notification in the system tray informing the user about that.
Now I would like to handle from Outlook Add-in the event that is fired when user clicks on the Windows notification popup in the system tray so that Outlook Add-in can open a new window to display all the information processed by the background process.
So is it possible to do it? If so, could you please provide me some code snippets or examples, or even some kind of guide to start in? I have google and I haven't found anything about that.
Yes, it is possible. But VSTO (nor Outlook) doesn't provide anything for that. That is a pure .net topic. Consider your VSTO add-in as a regular Windows application based on .net platform.
I suppose the NotifyIcon component is used for displaying a notification in the tray. In that case you can use the NotifyIcon.BalloonTipClicked event which is fired when the balloon tip is clicked.
The following code example demonstrates the use of this member. In the example, an event handler reports on the occurrence of the BalloonTipClicked event. This report helps you to learn when the event occurs and can assist you in debugging. To report on multiple events or on events that occur frequently, consider replacing MessageBox.Show with Console.WriteLine or appending the message to a multiline TextBox.
To run the example code, paste it into a project that contains an instance of type NotifyIcon named NotifyIcon1. Then ensure that the event handler is associated with the BalloonTipClicked event.
MessageBox.Show("You are in the NotifyIcon.BalloonTipClicked event.");
So you are trying to create a fake email in the Inbox folder that looks like it was received? You cannot force Outlook to display new message notification - that can only be done from a transport provider by calling IMAPISupport::Notify and passing fnewNewMail flag.
You can of course create a fake message in the Inbox folder that looks like it was received (a bit convoluted in OOM but very easy using Redemption (I am its author) or Extended MAPI).
The best you can do is create your own tray notification that will open the message and display it (MailItem.Display) when the user clicks on it.

BotFramework Composer: Avoiding unwanted interrupts from LUIS, but supporting 'cancel' across dialogs?

My bot has been created purely with BotFramework Composer. It has several dozen dialogs. The user's question is mapped to an intent with LUIS; it uses LUIS as the main recogniser. Each intent has its own dialog. Each dialog has many user text inputs, formalised as buttons for the user to click.
I'd like to support a typed 'cancel' across all these dialogs.
I can do this by adding an intent for it with LUIS, and allowing interrupts on the text input action. However, as a side effect, all the other LUIS intents come into play, and mess up my dialogs by launching new child dialogs – other than 'cancel' – into what should be a strict linear process. I only want it to recognise 'cancel' after the dialog has been started.
Is there some way to achieve this with Composer, other than adding a manual check for 'cancel' as user input after each text input action?

Is there an equivalent of an OnModal message in MFC?

My MFC application has multiple top level (parented to the desktop) windows, any one of which can host an external application which can launch a modal dialog. Is there a way for one the other top level windows to get a notification when any of the others becomes modal?
My specific problem is that one of the my windows is hosting an embedded PDF viewer and when the user clicks print, only the window hosting the viewer is locked, not the others.
When a modal dialog is shown EnableWindow(FALSE) is called for the parent. It is deactivated now and will not accept any mouse input. Also it will not receive the keyboard focus.
When EnableWindow(FALSE) is called WM_ENABLE with wParam==FALSE is sent to the window.
When your parent receives this message you can call EnableWindow(FALSE) for all your other windows too. Recursion might be a problem here, but you can use a private window message or flags to prevent this.
Before the modal dialog closes EnableWndow(TRUE) is called again and WM_ENABLE with wParam==TRUE is sent again.

How Do I Do Cool Dialog Stuff (MFC)

Whether I have to use a dialog box or a message doesn't really matter but I need to somehow do the following:
I've got a dialog-based MFC application. The main dialog calls a procedure that creates a thread. The call to the procedure is inside while loop. (Basically it's a file processing program - spawning off a thread for doing the file saving. So, a thread is spawned for each file that is being saved.)
I am suspending and resuming the main thread properly. However, I don't know how to get a message box/dialog box to display saying something like "please wait" and still have the main dialog update... 0.o
Basically, I want to lock the main dialog from user interaction (like keeping them from selecting anything or clicking any buttons), but I want the progress bar on the dialog to update...
Any ideas?
A bit old but does the work:
microsoft.com/msj/0297/wicked/wicked0297.aspx
Well, this is very old app.
You do not need to follow this sample; however you can follow the idea.
You have two choices:
Create progress bar in the main dialog, disable all dialog but progress. Start thread passing dialog’s handle. From the thread use this handle to send a custom message to allow dialog advancing progress.
Another message would notify dialog that thread is done and enable all controls.
Another choice would be to spawn modeless dialog, start the thread passing modeless dialog’s handle and process as described above.
Pass main dialog pointer to the modeless dialog to be used to disable and enable main dialog upon modeless start (OnInitDialog) and enable upon receiving thread complete message, before destroying modeless dialog window.

WM_POWERBROADCAST handler for CMainDlg in ATL app not invoked

I have an ATL app where I want to handle WM_POWERBROADCAST. I have a CMainDlg (CAxDialogImpl) in whose MSG_MAP I defined the handler.
BEGIN_MSG_MAP(CMainDlg)
...
MESSAGE_HANDLER(WM_POWERBROADCAST, OnPowerChange)
...
END_MSG_MAP()
However, the handler isn't invoked when I do things that should invoke it, for instance change power settings or put the machine to sleep.
Any ideas about what might be going on, and how to fix this? Does CMainDlg not get notified of power events, for some reason?
I suspect your dialog not being a top level window (WS_POPUP styled).
Just tested with a WTL AppWizard non modal dialog app that WM_POWERBROADCAST is received (without any registration) on AC plugged/unplugged.
Did you register to receive the power events?
To add to answers above, you might want to use Spy++ tool to make sure the messages of interest are posted to your application in first place. You will also see which windows they are posted to, and if it is your window where you are waiting for this message.

Resources