window bring to front, raise, show, TaskBarIcon, tooltips

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
[email protected]
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Jul 08, 2005 5:31 pm

window bring to front, raise, show, TaskBarIcon, tooltips

Post by [email protected] » Fri Jul 08, 2005 5:43 pm

Hi guys,

Brand new to wxWidgets and so far I like what I see. I'm trying to write a tiny little application to sit in the system tray in Windows and monitor a few things, and when it hits a certain event I want it to bring the window to the foreground (and perhaps eventually just pop a little bubble from the systray or something fancy like that).

Problem is, I've searched for about an hour and tried every last strategy I can, but none of them do what I want, which is to bring the window from the background to the foreground (if it's not in the foreground).

The closest I can get to it is to do:

Code: Select all

 frame->Iconize(true);
frame->Iconize(false);
which will drop the window and then bring it back up. But that's very annoying, b/c that's not exactly what I want. It's slow, and you see it dropping and coming back up.

These are some of the others that I've tried that mostly just end up flashing the taskbar entry for the program, which is okay (I might add that as well), but not what I'm looking for:

Code: Select all

frame->Raise();  // doesn't seem to work
frame->SetFocus();  // does nothing
frame->Show(true); // this by itself doesn't work
frame->RequestUserAttention();
Oh, and this is a single frame, very simple application. The frame I mostly borrowed from the samples/socket/client.cpp example. It just does some event handling. Also, I'm running this in WinXP Pro, SP2.

Anyone have *any* idea what I'm running into here? I'm using C++ under the MinGW Dev Studio, which has worked pretty well for me. This includes one of the latest builds of wxWidgets, 2.6.x I think.
Last edited by [email protected] on Mon Jul 11, 2005 10:23 pm, edited 1 time in total.

lowjoel
Moderator
Moderator
Posts: 1511
Joined: Sun Jun 19, 2005 11:37 am
Location: Singapore
Contact:

Post by lowjoel » Fri Jul 08, 2005 11:15 pm

i dont know if my pi calculator has what you want... have a look: http://joelsplace.sg/studyroom/index.php if im not wrong that is what you want... if it is, then well basically because its computationally intensive ill leave it at the tray until something crops up... of which im about to add a balloon tooltip (win32api for mingw isnt complete for xp and up). otherewise it just shuts up

[email protected]
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Jul 08, 2005 5:31 pm

Post by [email protected] » Mon Jul 11, 2005 10:22 pm

lowjoel wrote:i dont know if my pi calculator has what you want... have a look: http://joelsplace.sg/studyroom/index.php if im not wrong that is what you want... if it is, then well basically because its computationally intensive ill leave it at the tray until something crops up... of which im about to add a balloon tooltip (win32api for mingw isnt complete for xp and up). otherewise it just shuts up
Yeah, this sounds great. I'd rather not install your program to see the results, I believe you. But I need to see at least partial source code. What you describe is really exactly what I'm trying to do.

Would you mind sharing the code that enables the TaskBarIcon and also the tooltips? Or perhaps you're saying you've not yet implemented the tooltips. There's another thread here discussing how to do this as of last fall:

http://forums.wxwidgets.org/viewtopic.p ... t=set+icon

Hope that helps you. I'm trying to get the tooltip stuff to work right now, and not having much luck. But then again, I'm new to all of this wxWidgets stuff, and it's been awhile since I've done much C/C++ coding. I'm using mingw32 too.

Also, I should mention I've had preliminary success with TaskBarIcon. I can create one, see it in the systray, set an icon on it, etc. My main problem comes in when I close the program. The program stays loaded, even though the main frame is closed. Even if I use ->RemoveIcon() on the TBI object, the icon goes away, but the program is still running. I've tried using the destructor and a couple of other things, but it's just not working. Very annoying. Any ideas?

kai7
Knows some wx things
Knows some wx things
Posts: 40
Joined: Wed Sep 28, 2005 11:02 am
Location: Germany, Berlin
Contact:

Post by kai7 » Wed Sep 28, 2005 11:19 am

Hi,

have you meanwhile solved the problem to bring the application window to the front? Actually I have a solution which is working only under Windows (it uses the Win32API). Here is the code:

Code: Select all

bool ForceForegroundWindow(HWND hwnd)
{
   // Code from Thomas Stutz @ delphi3000.com
   // Converted to Borland C++ Builder Code by Wolfgang Frisch
   // Converted to a Borland independent version by Kai Schaeffer @ schaeffer-ag.de

   bool Result;

   #define SPI_GETFOREGROUNDLOCKTIMEOUT (0x2000)
   #define SPI_SETFOREGROUNDLOCKTIMEOUT (0x2001)

   DWORD nullvalue = 0;

   DWORD ForegroundThreadID;
   DWORD ThisThreadID;
   DWORD timeout;

   if(IsIconic(hwnd)) ShowWindow(hwnd, SW_RESTORE);

   if(GetForegroundWindow()==hwnd) return true;
   else
   {
       // Windows 98/2000 doesn't want to foreground a window when some other
       // window has keyboard focus
       OSVERSIONINFO VersionInfo;
       VersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
       GetVersionEx(&VersionInfo);
       int Win32Platform=VersionInfo.dwPlatformId;
       int Win32MajorVersion=VersionInfo.dwMajorVersion;
       int Win32MinorVersion=VersionInfo.dwMinorVersion;
       int Win32BuildNumber=VersionInfo.dwBuildNumber;
       if( ((Win32Platform == VER_PLATFORM_WIN32_NT) && (Win32MajorVersion> 4))
           || ((Win32Platform == VER_PLATFORM_WIN32_WINDOWS)
           && ((Win32MajorVersion > 4) || ((Win32MajorVersion == 4) &&
           (Win32MinorVersion > 0)))) )
       {
           // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
           // Converted to Delphi by Ray Lischner
           // Published in The Delphi Magazine 55, page 16

           Result = false;
           ForegroundThreadID =GetWindowThreadProcessId(GetForegroundWindow(),NULL);
           ThisThreadID = GetWindowThreadProcessId(hwnd,NULL);
           if( AttachThreadInput(ThisThreadID, ForegroundThreadID, true) )
           {
             BringWindowToTop(hwnd); // IE 5.5 related hack
             SetForegroundWindow(hwnd);
             AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
             Result = (GetForegroundWindow() == hwnd);
           }
           if(!Result)
           {
             // Code by Daniel P. Stasinski
             SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,&timeout, 0);
             SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,&nullvalue,
                                  SPIF_SENDCHANGE);
             BringWindowToTop(hwnd); // IE 5.5 related hack
             SetForegroundWindow(hwnd);
             SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
             &timeout, SPIF_SENDCHANGE);
           }
       }
       else
       {
         BringWindowToTop(hwnd); // IE 5.5 related hack
         SetForegroundWindow(hwnd);
       }
       Result = (GetForegroundWindow() == hwnd);
   } return Result;
}
A call like "ForceForegroundWindow((HWND)GetHandle());" brings the window to the front in nearly every situation. I had the problem a while ago for an application written with the C++ Builder. Now I am porting it to wxWidgets an adjusted the code. If you have a more platform independent solution I would be interested (the question is if it is a problem on other platforms :-) )

-Kai

makeinstallclean
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sun Feb 05, 2006 6:44 pm

Post by makeinstallclean » Sun Feb 12, 2006 11:08 pm

It took some time to figure out but this worked for me:

Code: Select all

  ParentWindow->Iconize(false); // restore the window if minimized
  ParentWindow->SetFocus();  // focus on my window
  ParentWindow->Raise();  // bring window to front
  ParentWindow->Show(true); // show the window
I dont know if this is over kill but after many attempts this combo worked for me.

kai7
Knows some wx things
Knows some wx things
Posts: 40
Joined: Wed Sep 28, 2005 11:02 am
Location: Germany, Berlin
Contact:

Post by kai7 » Wed Mar 29, 2006 2:33 pm

It took some time to figure out but this worked for me: ...
This is working well under Linux and MacOSX... but under Windows it only produces a flashing of the application in the task bar. So it seems that there is one straight solution for most plattforms and one not so straight for Windows. What a surprise. :wink:

chris
I live to help wx-kind
I live to help wx-kind
Posts: 150
Joined: Fri Oct 08, 2004 2:05 pm
Location: Europe

Post by chris » Wed Mar 29, 2006 11:24 pm

I'm using this:

Code: Select all

win->SetFocus();
win->Raise();
win->Show(true);
#ifdef __WXMSW__
win->Maximize(false);
#endif
This is used to bring back an iconized wxWindow on the front, which is what you were looking for, I think.
It works as expected on wxMSW and wxGTK; didn't test it on Mac.

HTH, Chris
this->signature=NULL;

kai7
Knows some wx things
Knows some wx things
Posts: 40
Joined: Wed Sep 28, 2005 11:02 am
Location: Germany, Berlin
Contact:

Post by kai7 » Thu Mar 30, 2006 6:54 am

Code: Select all

#ifdef __WXMSW__
win->Maximize(false);
#endif
OK, this is a nice workaround which is working well... if you don't have a maximized window. If your window is maximized it is as expected restored afterwards. A more funny result you get with:

Code: Select all

#ifdef __WXMSW__
win->Maximize(true);
#endif
If your window isn't maximizied it is afterwards. But if it is maximized it's getting restored and instantly maximized again.

However changing the maximized state of a window while brining it to the front is a behaivour that is IMHO not acceptable. Is there a workaround for this?

Usky_yahooo
In need of some credit
In need of some credit
Posts: 4
Joined: Thu Oct 04, 2007 2:00 pm

Post by Usky_yahooo » Tue Oct 09, 2007 11:26 am

Maybe this code will work right

void wxTaskBarIconEx::OnTaskBarIconLeftClicked(wxTaskBarIconEvent& event)
{

if(m_pMainFrame->IsIconized())
{
m_pMainFrame->Show(true);//Show the frame
m_pMainFrame->Iconize(false);//restore the taskbar window
}
else
{
m_pMainFrame->Show(false);//hide the window
m_pMainFrame->Iconize(true);//minimize the window
}

if(!IsIconInstalled())
SetIcon(*m_pIcon);

//#ifdef __WXMSW__
// m_pMainFrame->Maximize(false);//Bring window to the front
//#endif
// wxMessageBox(wxT("Icon clicked"));

}
but you also need this sentence:
wxFrame *m_pMainFrame;

And the following:

void Reminder2Frame::OnFrameIconize(wxIconizeEvent& event)
{
this->Show(false);
}

TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV » Sat Sep 27, 2008 12:09 pm

I'ld like to add my experience...

When you iconize the frame, you've got to add after iconizing

Code: Select all

Show(false)

in order to remove the app from the taskbar

and before de-iconizing

Code: Select all

Show(true)
in order to display the frame on the foreground

That's all. So here's the code necessary to have an app
- running in background in systray only
- with a 'Quit' option in menu
- with a 'close' button turned into an 'iconize' action
- with a systray icon popup menu with a 'Open/Minimize' option and with a 'Quit' option

MyFrame.h

Code: Select all

[...]
#include "MyTaskBarIcon.h"

class MyFrame : public wxFrame
{
    public:
    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
    ~MyFrame();

    void OnMenuQuit(wxCommandEvent& WXUNUSED(event)); // actions executed when 'Quit' menu item is selected
    void OnIconizeWindow(wxIconizeEvent& event); // actions executed when the frame is iconized
    void OnCloseWindow(wxCloseEvent& WXUNUSED(event)); // actions executed when the frame is closed
    [...]

    private:
    void MinimizeApplication();
    void QuitApplication();
    [...]

    MyTaskBarIcon* trayIcon; // taskbar icon

    DECLARE_EVENT_TABLE()
};
MyFrame.cpp

Code: Select all

[...]
#include "MyFrame.h"
#include "AppIcon.xpm"

[...]

int idMenuQuit = ::wxNewId();

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(idMenuQuit, MyFrame::OnMenuQuit)
    EVT_CLOSE(MyFrame::OnCloseWindow)
    EVT_ICONIZE(MyFrame::OnIconizeWindow)
END_EVENT_TABLE()

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame*)NULL, -1, title, pos, size)
{
    this->trayIcon = new MyTaskBarIcon(this); // creates taskbar icon
    this->trayIcon->SetIcon(wxIcon(AppIcon_xpm), "AppName"); // sets taskbar icon image and name
    
    [...]
}

MyFrame::~MyFrame()
{
    delete this->trayIcon;
}

[...]

//*** application management

void MyFrame::MinimizeApplication()
{
    this->Iconize(true); // iconizes the frame, thus generating an iconize event
}

void MyFrame::QuitApplication()
{
    this->trayIcon->RemoveIcon(); // removes tray icon
    this->Destroy(); // destroys the frame, thus the application
}

//*** menu events

void MyFrame::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
{
    this->QuitApplication();
}

[...]

//*** frame events

void MyFrame::OnIconizeWindow(wxIconizeEvent& event)
{
    if ( event.Iconized() ) { // if the event reports that the frame has just been iconized
        this->Show(false); // removes minimized window from taskbar, leaving only systray icon
    }
}

void MyFrame::OnCloseWindow(wxCloseEvent& event)
{
    this->MinimizeApplication();
}
MyTaskBarIcon.h

Code: Select all

[...]
#include <wx/taskbar.h>

class MyFrame;  // declaration for cross-reference MyFrame <-> MyTaskBarIcon

class MyTaskBarIcon : public wxTaskBarIcon {
    public:
    MyTaskBarIcon(MyFrame* frame);

    void OnTrayClick(wxTaskBarIconEvent& WXUNUSED(event)); // actions executed when tray menu icon is clicked
    void OnTrayOpenMinimize(wxCommandEvent& WXUNUSED(event)); // actions executed when 'Open/Minimize' tray menu item is selected
    void OnTrayQuit(wxCommandEvent& WXUNUSED(event)); // actions executed when 'Quit' tray menu item is selected

    private:
    void SwapIconize();

    MyFrame* mainFrame; // reference to GUI
    [...]

    DECLARE_EVENT_TABLE()
};
MyTaskBarIcon.cpp

Code: Select all

[...]
#include "MyFrame.h"
#include "MyTaskBarIcon.h"

int idTrayOpenMinimize = ::wxNewId();
int idTrayQuit = ::wxNewId();

BEGIN_EVENT_TABLE(MyTaskBarIcon, wxTaskBarIcon)
    EVT_MENU(idTrayOpenMinimize, MyTaskBarIcon::OnTrayOpenMinimize)
    EVT_MENU(idTrayQuit, MyTaskBarIcon::OnTrayQuit)

    EVT_TASKBAR_LEFT_DCLICK(MyTaskBarIcon::OnTrayClick)
END_EVENT_TABLE()


MyTaskBarIcon::MyTaskBarIcon(MyFrame* frame)
: wxTaskBarIcon()
, mainFrame(frame)
{
}


//*** overriden methods

wxMenu* MyTaskBarIcon::CreatePopupMenu()
{
    this->menuTray = new wxMenu();

    this->menuTray->Append(idTrayOpenMinimize, "Open/Minimize");
    this->menuTray->AppendSeparator();
    this->menuTray->Append(idTrayQuit, "Quit");

    return this->menuTray;
}


//*** common methods

void MyTaskBarIcon::SwapIconize()
{
    if ( this->mainFrame->IsIconized() ) { // if the frame is iconized
        this->mainFrame->Show(true); // shows the frame before to de-iconize it, thus displays frame on foreground
        this->mainFrame->Iconize(false); // de-iconizes the frame, thus generating an iconize event
    }
    else { // if the frame is not iconized
        this->mainFrame->MinimizeApplication();
    }
}


//*** menu events

void MyTaskBarIcon::OnTrayOpenMinimize(wxCommandEvent& WXUNUSED(event))
{
    this->swapIconize();
}

void MyTaskBarIcon::OnTrayQuit(wxCommandEvent& WXUNUSED(event))
{
    this->mainFrame->QuitApplication();
}


//*** click events

void MyTaskBarIcon::OnTrayClick(wxTaskBarIconEvent& WXUNUSED(event))
{
    this->SwapIconize();
}
Last edited by TrV on Thu Mar 04, 2010 12:29 am, edited 5 times in total.

knightmare0
Experienced Solver
Experienced Solver
Posts: 65
Joined: Sat Mar 29, 2008 9:18 pm

Post by knightmare0 » Tue Dec 16, 2008 2:32 am

makeinstallclean wrote:It took some time to figure out but this worked for me:

Code: Select all

  ParentWindow->Iconize(false); // restore the window if minimized
  ParentWindow->SetFocus();  // focus on my window
  ParentWindow->Raise();  // bring window to front
  ParentWindow->Show(true); // show the window
I dont know if this is over kill but after many attempts this combo worked for me.


OMFG!!! IT WORKED I LOVE YOU MAN!!!!!!! THANKS!!! I been trying to work with this shit for a long time now... it really shouldn't be this annoying.

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Thu Mar 04, 2010 10:45 am

Thanks TRV
That is beautiful snippet
Saving alot of pain!
Thanks :o
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

Crocodillian
In need of some credit
In need of some credit
Posts: 1
Joined: Fri Mar 22, 2019 8:28 pm

Re: window bring to front, raise, show, TaskBarIcon, tooltips

Post by Crocodillian » Fri Mar 22, 2019 8:30 pm

Unfortunately this no longer works.

User avatar
doublemax
Moderator
Moderator
Posts: 15828
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: window bring to front, raise, show, TaskBarIcon, tooltips

Post by doublemax » Fri Mar 22, 2019 9:59 pm

Crocodillian wrote:
Fri Mar 22, 2019 8:30 pm
Unfortunately this no longer works.
This thread is over 10 years old. Please explain what you're trying to do and what doesn't work.
Use the source, Luke!

Post Reply