Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Click event is not fired from Action Center #35

Open
malja opened this issue Apr 30, 2018 · 10 comments
Open

Click event is not fired from Action Center #35

malja opened this issue Apr 30, 2018 · 10 comments

Comments

@malja
Copy link
Contributor

malja commented Apr 30, 2018

Hi all,

I'm using following code (basically simplified WinToast example) to create a notification with attached event handler and one action:

#include "wintoastlib.h"
#include <string>

using namespace WinToastLib;

class CustomHandler : public IWinToastHandler {
public:
	void toastActivated() const {
		std::wcout << L"The user clicked in this toast" << std::endl;
	}

	void toastActivated(int actionIndex) const {
		std::wcout << L"The user clicked on action #" << actionIndex << std::endl;
	}

	void toastDismissed(WinToastDismissalReason state) const {
		switch (state) {
		case UserCanceled:
			std::wcout << L"The user dismissed this toast" << std::endl;
			break;
		case TimedOut:
			std::wcout << L"The toast has timed out" << std::endl;
			break;
		case ApplicationHidden:
			std::wcout << L"The application hid the toast using ToastNotifier.hide()" << std::endl;
			break;
		default:
			std::wcout << L"Toast not activated" << std::endl;
			break;
		}
	}

	void toastFailed() const {
		std::wcout << L"Error showing current toast" << std::endl;
	}
};

int main() {

	std::wstring appName = L"Console WinToast Example",
		appUserModelID = L"WinToast Console Example",
		text = L"Test";

	WinToast::instance()->setAppName(appName);
	WinToast::instance()->setAppUserModelId(appUserModelID);

	if (!WinToast::instance()->initialize()) {
		std::wcerr << L"Error, your system in not compatible!" << std::endl;
		return -1;
	}

	WinToastTemplate templ(WinToastTemplate::Text01);
	templ.setTextField(text, WinToastTemplate::FirstLine);
	templ.addAction(L"Action");
	templ.setDuration(WinToastTemplate::Duration::Short);

	WinToast::instance()->showToast(templ, new CustomHandler());

	Sleep(15000);

	return 0;
}

The problem is, when notification is moved to Action Center (after short duration expires), either toastActivated(void) nor the toastActivated(int) method of CustomHandler is called.

Is something wrong with the code, or is this normal and intended behavior? If so, I need to get them working from Action Center, is there a way?

Thank you.

@mohabouje
Copy link
Owner

I'm not sure, but I think that the App User Model ID is not a valid one, the expect format is the one that you can find in this link:

CompanyName.ProductName.SubProduct.VersionInformation

There is a helper function in the class to avoid those problems. Try it and I will try to figure out a way to reproduce the problem.

@malja
Copy link
Contributor Author

malja commented May 2, 2018

Yes, you are rigth, I changed it to:

std::wstring appName = L"test";
std::wstring text = L"Notification test";

WinToast::instance()->setAppName(appName);
WinToast::instance()->setAppUserModelId(
    WinToast::instance()->configureAUMI(L"company", L"product", L"subproduct", L"version")
);

But the issue persist. To reproduce it, follow those steps:

  1. Run compiled code posted in the first comment (with changes above)
  2. Wait until notification moves to Action Center
  3. Open Action Center
  4. Try to click on notification or on action button.

In my case, the last event I see in console is "Toast has timed out". Method toastActivated() is not called at all.

@malja
Copy link
Contributor Author

malja commented May 17, 2018

Hi @mohabouje, is there any update on this?

@jiakuan
Copy link

jiakuan commented Jun 1, 2018

I encountered the same issue. Once a notification message disappears and goes to Windows Action Center, click event is not triggered when clicking on the notification from Action Center.

@mohabouje
Copy link
Owner

@malja @jiakuan guys, this is not implemented yet If you check the src code you will find a link with the modifications to be implemented. The library need to create a notification activator:

// The UUID CLSID must be unique to your app. Create a new GUID if copying this code.
class DECLSPEC_UUID("replaced-with-your-guid-C173E6ADF0C3") NotificationActivator WrlSealed WrlFinal
    : public RuntimeClass<RuntimeClassFlags<ClassicCom>, INotificationActivationCallback>
{
public:
    virtual HRESULT STDMETHODCALLTYPE Activate(
        _In_ LPCWSTR appUserModelId,
        _In_ LPCWSTR invokedArgs,
        _In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA* data,
        ULONG dataCount) override
    {
        // TODO: Handle activation
    }
};

// Flag class as COM creatable
CoCreatableClass(NotificationActivator);

Then you have to register AUMID and the COM server:

// Register AUMID and COM server (for Desktop Bridge apps, this no-ops)
hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(L"YourCompany.YourApp", __uuidof(NotificationActivator));
// Register activator type
hr = DesktopNotificationManagerCompat::RegisterActivator();

All the information can be found here:

Send a local toast notification from desktop C++ WRL apps

Right now, I'm a little bit busy but I will try to do it as soon as possible. You are free to implement it by yourself and create a PR to share with the community! Any contribution is welcome!

malja pushed a commit to malja/WinToast that referenced this issue Jun 13, 2018
@malja
Copy link
Contributor Author

malja commented Sep 3, 2018

@mohabouje I am sorry for the delay. I had no time for programming lately. But yesterday I basically did step by step follow up of linked tutorial. But my Activator class is never called. As far as I know.

What works is that program is executed with -ToastActivated command line parameter. This may be one way of handling notifications. But no additional info is passed with it - the program does not know which notification did start it.

In addition, I have not found a way of defining UUID for Activator class dynamicaly on runtime. This could be problem from python binding later on.

My source code: https://github.com/malja/WinToast/tree/background/WinToast

PS: Notifications are not removed from Action Center when clicked. This should be implemented in Activator class. There is a tutorial on it. But it involves notification tags. And I wanted the code to stay as simple as possible before all bugs are fixed.

Any ideas?

@rcohn
Copy link

rcohn commented Apr 15, 2019

Hi -

I'll try to dig into this a bit more on my own, but do you know why I would be able to run the WinToast console demo from Visual Studio, yet not be able to run it as a standalone (or from the start menu, where the demo installs it as "yolo")? The console window flashes and then nothing happens.

Thank you.

@rcohn
Copy link

rcohn commented Apr 17, 2019

OK. The solution is rather simple. I was trying to execute the program without any arguments. The console flashed briefly and the program quit. Running that console app from another cmd window shows the help args listed out. Once I added command args, the app works normally.

Thanks.

@ZhangTianrong
Copy link

ZhangTianrong commented May 4, 2021

@mohabouje Any update on this?

@mohabouje
Copy link
Owner

mohabouje commented Apr 10, 2023

Trying to follow @malja and @rcohn changes to implement a standard way or provide some documentation for the users to implement this. I plan to make these changes part of version v1.4.0. PRs are welcome if anyone has a better approach to doing this.

Please see #86 for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants