Board index » cppbuilder » Popup Bubble Messages

Popup Bubble Messages


2004-11-04 02:09:06 AM
cppbuilder62
I've got a program that is contained to the system tray, for the most part.
I'd like to have it popup a bubble message, when it needs the user's
attention. Like the ones that Microsoft's automatic update uses. Does anyone
know a way to create and display these popup bubbles?
Thanks,
Jeff
 
 

Re:Popup Bubble Messages

"Jeff" < XXXX@XXXXX.COM >wrote in message
Quote
I've got a program that is contained to the system tray, for the most
part. I'd like to have it popup a bubble message, when it needs the
user's attention. Like the ones that Microsoft's automatic update uses.
Does anyone know a way to create and display these popup bubbles?
That is a normal Tooltip window that has the TTS_BALLOON style enabled.
Look here for more information:
Using ToolTip Controls
msdn.microsoft.com/library/en-us/shellcc/platform/commctls/tooltip/usingtooltips.asp
The VCL does not natively support balloon tooltips, so you will have to code
it manually.
Gambit
 

Re:Popup Bubble Messages

Thank you, that's what I've been looking for.
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Jeff" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I've got a program that is contained to the system tray, for the most
>part. I'd like to have it popup a bubble message, when it needs the
>user's attention. Like the ones that Microsoft's automatic update uses.
>Does anyone know a way to create and display these popup bubbles?

That is a normal Tooltip window that has the TTS_BALLOON style enabled.
Look here for more information:

Using ToolTip Controls

msdn.microsoft.com/library/en-us/shellcc/platform/commctls/tooltip/usingtooltips.asp

The VCL does not natively support balloon tooltips, so you will have to
code
it manually.


Gambit


 

{smallsort}

Re:Popup Bubble Messages

I've coded up their example, but the GetClientRect() function is being
overwritten by TCustomForm. It's saying I've got too many parameters,
because the BCB function doesn't take any parameters. How do I specify
access to the API function?
Here's what I've got coded so far:
hwndToolTips = CreateWindow(TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_BALLOON,
0, 0,
0, 0,
NULL, NULL,
TrayIcon->Handle,
NULL);
TOOLINFO ti;
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_TRANSPARENT | TTF_CENTERTIP;
ti.hwnd = TrayIcon->Handle;
ti.uId = 0;
ti.hinst = NULL;
ti.lpszText = ptr_chrText;
GetClientRect(TrayIcon->Handle, &ti.rect);
SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti );
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Jeff" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I've got a program that is contained to the system tray, for the most
>part. I'd like to have it popup a bubble message, when it needs the
>user's attention. Like the ones that Microsoft's automatic update uses.
>Does anyone know a way to create and display these popup bubbles?

That is a normal Tooltip window that has the TTS_BALLOON style enabled.
Look here for more information:

Using ToolTip Controls

msdn.microsoft.com/library/en-us/shellcc/platform/commctls/tooltip/usingtooltips.asp

The VCL does not natively support balloon tooltips, so you will have to
code
it manually.


Gambit


 

Re:Popup Bubble Messages

"Jeff" < XXXX@XXXXX.COM >wrote in message
Quote
I've coded up their example, but the GetClientRect()
function is being overwritten by TCustomForm.
Prefix the call with the "::" global namespace in order to use the API
function rather than the VCL function:
::GetClientRect(TrayIcon->Handle, &ti.rect);
Gambit
 

Re:Popup Bubble Messages

Thanks, that worked.
My code compiles now, but no bubble pops up? What am I doing wrong?
My function is:
void __fastcall TfrmMain::PopupMessage(char *ptr_chrText)
{
hwndToolTips = CreateWindow(TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_BALLOON,
0, 0,
0, 0,
NULL, NULL,
TrayIcon->Handle,
NULL);
TOOLINFO ti;
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_TRANSPARENT | TTF_CENTERTIP;
ti.hwnd = TrayIcon->Handle;
ti.uId = 0;
ti.hinst = NULL;
ti.lpszText = ptr_chrText;
::GetClientRect(TrayIcon->Handle, &ti.rect);
SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti );
}
My definition is: HWND hwndToolTips;
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Jeff" < XXXX@XXXXX.COM >wrote in message
news:418942ee$ XXXX@XXXXX.COM ...

>I've coded up their example, but the GetClientRect()
>function is being overwritten by TCustomForm.

Prefix the call with the "::" global namespace in order to use the API
function rather than the VCL function:

::GetClientRect(TrayIcon->Handle, &ti.rect);


Gambit


 

Re:Popup Bubble Messages

"Jeff" < XXXX@XXXXX.COM >wrote in message
Quote
My code compiles now, but no bubble pops up? What am I doing wrong?
You didn't specify where or when you are actually calling PopupMessage()
from.
You also never actually display the tooltip after you create it.
You also appear to be making an assumptiong that you should not be making -
you appear to be assuming that the TrayIcon->Handle represents the actual
icon in the system tray. It does not.
You also didn't read the documentation that I pointed you to very carefully,
or you would have seen the section titled "Balloon ToolTips for Status Bar
Icons", which describes the exact situation that you were originally asking
about.
Gambit
 

Re:Popup Bubble Messages

Quote
You didn't specify where or when you are actually calling PopupMessage()
from.
I just call this function from a button click event right now, to test
it.
Quote
You also never actually display the tooltip after you create it.
You also appear to be making an assumptiong that you should not be
making -
you appear to be assuming that the TrayIcon->Handle represents the actual
icon in the system tray. It does not.
I'm sorry, I've only worked with this level of the API once in my life.
Forgive me, I don't know much about it, that's why I'm asking questions
here. What does it represent?
Quote
You also didn't read the documentation that I pointed you to very
carefully,
or you would have seen the section titled "Balloon ToolTips for Status Bar
Icons", which describes the exact situation that you were originally
asking
about.
I did read that section, I've been trying different methods, but
SendMessage always seems to return a false. The next thing I'll try is the
exact code that is in that section.
Thanks,
Jeff
 

Re:Popup Bubble Messages

"Jeff" < XXXX@XXXXX.COM >wrote in message
Quote
I did read that section, I've been trying different methods
But, did you do what the "Balloon ToolTips for Status Bar Icons" section
actually told you to do? It even gives an actual code snippet that shows
how to put these tooltips onto the status icon.
Quote
but SendMessage always seems to return a false.
It does not sound like you are using it correctly at all. Please show your
code.
Quote
The next thing I'll try is the exact code that is in that section.
You should have tried that code from the beginning as soon as I pointed you
to it.
Gambit
 

Re:Popup Bubble Messages

My Code:
void __fastcall TfrmMain::PopupMessage(char *ptr_chrText)
{
NOTIFYICONDATA IconData = {0};
TOOLINFO ti;
bool Good;
hwndToolTips = CreateWindow(TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_BALLOON,
0, 0,
0, 0,
NULL, NULL,
Application->Handle,
NULL);
if (hwndToolTips)
{
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_TRANSPARENT | TTF_CENTERTIP;
ti.hwnd = Application->Handle;
ti.uId = 0;
ti.hinst = NULL;
ti.lpszText = ptr_chrText;
::GetClientRect(Application->Handle, &ti.rect);
Good = SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti );
if (Good)
Application->MessageBox("Success!","Message",MB_OK);
else
Application->MessageBox("Failed!","Message",MB_OK);
}
IconData.cbSize = sizeof(IconData);
IconData.hWnd = hwndToolTips;
IconData.uFlags = NIF_INFO;
IconData.uTimeout = 15000; // in milliseconds
StrLCopy(IconData.szInfo, ptr_chrText, ARRAYSIZE(IconData.szInfo));
Good = Shell_NotifyIcon(NIM_MODIFY, &IconData);
if (Good)
Application->MessageBox("Success!","Message",MB_OK);
else
Application->MessageBox("Failed!","Message",MB_OK);
}
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Jeff" < XXXX@XXXXX.COM >wrote in message
news:418976ee$ XXXX@XXXXX.COM ...

>I did read that section, I've been trying different methods

But, did you do what the "Balloon ToolTips for Status Bar Icons" section
actually told you to do? It even gives an actual code snippet that shows
how to put these tooltips onto the status icon.

>but SendMessage always seems to return a false.

It does not sound like you are using it correctly at all. Please show
your
code.

>The next thing I'll try is the exact code that is in that section.

You should have tried that code from the beginning as soon as I pointed
you
to it.


Gambit



 

Re:Popup Bubble Messages

"Jeff" < XXXX@XXXXX.COM >wrote in message
Quote
My Code:
You still did not pay attention to the documentation carefully enough. To
put a balloon toltip onto the status icon, you *do not* call CreateWindow()
yourself at all. You only fill in the NOTIFYICONDATA structure with the
relavant data and then Windows itself will create and display the tooltip
for you automatically. Your code should look like this instead:
void __fastcall TfrmMain::PopupMessage(char *ptr_chrText)
{
NOTIFYICONDATA IconData = {0};
IconData.cbSize = sizeof(IconData);
IconData.hWnd = this->Handle;
IconData.uFlags = NIF_INFO;
IconData.uTimeout = 15000; // in milliseconds
IconData.dwInfoFlags = NIIF_INFO;
StrLCopy(IconData.szInfo, ptr_chrText, 255);
StrLCopy(IconData.szInfoTitle, "My Balloon Title Here, 63);
if( Shell_NotifyIcon(NIM_MODIFY, &IconData) )
Application->MessageBox("Success!","Message",MB_OK);
else
Application->MessageBox("Failed!","Message",MB_OK);
}
Gambit
 

Re:Popup Bubble Messages

Thank you, that worked, I'm sorry for the confusion.
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Jeff" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>My Code:

You still did not pay attention to the documentation carefully enough. To
put a balloon toltip onto the status icon, you *do not* call
CreateWindow()
yourself at all. You only fill in the NOTIFYICONDATA structure with the
relavant data and then Windows itself will create and display the tooltip
for you automatically. Your code should look like this instead:

void __fastcall TfrmMain::PopupMessage(char *ptr_chrText)
{
NOTIFYICONDATA IconData = {0};

IconData.cbSize = sizeof(IconData);
IconData.hWnd = this->Handle;
IconData.uFlags = NIF_INFO;
IconData.uTimeout = 15000; // in milliseconds
IconData.dwInfoFlags = NIIF_INFO;
StrLCopy(IconData.szInfo, ptr_chrText, 255);
StrLCopy(IconData.szInfoTitle, "My Balloon Title Here, 63);

if( Shell_NotifyIcon(NIM_MODIFY, &IconData) )
Application->MessageBox("Success!","Message",MB_OK);
else
Application->MessageBox("Failed!","Message",MB_OK);
}


Gambit


 

Re:Popup Bubble Messages

Quote
void __fastcall TfrmMain::PopupMessage(char *ptr_chrText)
{
NOTIFYICONDATA IconData = {0};

IconData.cbSize = sizeof(IconData);
IconData.hWnd = this->Handle;
IconData.uFlags = NIF_INFO;
IconData.uTimeout = 15000; // in milliseconds
IconData.dwInfoFlags = NIIF_INFO;
StrLCopy(IconData.szInfo, ptr_chrText, 255);
StrLCopy(IconData.szInfoTitle, "My Balloon Title Here, 63);

if( Shell_NotifyIcon(NIM_MODIFY, &IconData) )
Application->MessageBox("Success!","Message",MB_OK);
else
Application->MessageBox("Failed!","Message",MB_OK);
}

Remy, I have tried this example with code changed a bit for use with
'any' control in my application, but am having no such luck... Can you help?
Here is what I have so far... not sure if its in the right place, but I used
the ApplicationEvents component to trap this event..
void __fastcall TMainForm::ApplicationEvents1ShowHint(AnsiString &HintStr,
bool &CanShow, THintInfo &HintInfo)
{
HintInfo.HideTimeout = 4000;
HWND hwndToolTips;
hwndToolTips = CreateWindow(TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_BALLOON,
0, 0,
0, 0,
NULL, NULL,
Application->Handle,
NULL);
if (hwndToolTips)
{
// Do the standard ToolTip coding.
TOOLINFO ti;
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_TRANSPARENT | TTF_CENTERTIP;
ti.hwnd = HintInfo.HintControl;
ti.uId = 0;
ti.hinst = NULL;
ti.lpszText = LPSTR_TEXTCALLBACK;
::GetClientRect(Application->Handle, &ti.rect);
SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti );
}
Thanks,
Lynn
 

Re:Popup Bubble Messages

"Lynn Morrison" < XXXX@XXXXX.COM >wrote in message
Quote
Remy, I have tried this example with code changed a bit
for use with 'any' control in my application, but am having no
such luck...
Nor should you, because the code you quoted is not designed for that. It
has a very specific purpose that cannot be adapted.
Quote
Here is what I have so far... not sure if its in the right place, but
I used the ApplicationEvents component to trap this event..
I would suggest a completely different approach - derive a new class from
THintWindow and have it set the balloon attributes for its own internal
Handle via its CreateParams() method. Then you simply set the
HintInfo.HintWindowClass member when displaying hints. In fact, you can set
the global HintWindowClass variable and not even use the OnShowHint event at
all.
Quote
ti.hwnd = HintInfo.HintControl;
That will not work. The hwnd member expects a HWND window handle, not a
TControl* pointer. You would have to first cast the HintControl to a
TWinControl* pointer in order to gain access to a suitable HWND window
handle.
Quote
::GetClientRect(Application->Handle, &ti.rect);
That will not work, either. The TApplication::Handle property represents a
hidden window. You should be using the HintControl's Handle instead. Which
would again require you to first cast the HintControl to a TWinControl*
first. Which means that your approach to handling hints will not work for
non-windowed controls at all, since they do not have window handles to begin
with.
Gambit
 

Re:Popup Bubble Messages

Quote
I would suggest a completely different approach - derive a new class from
THintWindow and have it set the balloon attributes for its own internal
Handle via its CreateParams() method. Then you simply set the
HintInfo.HintWindowClass member when displaying hints. In fact, you can
set
the global HintWindowClass variable and not even use the OnShowHint event
at
all.

Ok, I did this like you suggested...
class TMyHintWindow : public THintWindow
{
public:
__fastcall TMyHintWindow(Classes::TComponent *Owner):THintWindow(Owner) {}
__fastcall ~TMyHintWindow() {}
void __fastcall CreateParams(TCreateParams &Params);
};
void __fastcall TMyHintWindow::CreateParams(TCreateParams & Params)
{
Params.Style = WS_POPUP | TTS_NOPREFIX | TTS_BALLOON | WS_VISIBLE;
}
//---------main.h
class TMainForm: public TForm
{
TMyHintWindow *MHintWindow;
};
//---------main.cpp
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
MHintWindow = new TMyHintWindow(Owner);
::HintWindowClass = (TMetaClass*)MHintWindow;
}
The error I'm getting is,
[Linker Error] Unresolved external '__fastcall
Controls::THintWindow::NCPaint(void *)' referenced from
D:\BDEV\BRFTP\UNIT2.OBJ
I tried to cast ::HintWindowClass to TObject, but it did not like that at
all...
Where am I going wrong?
Lynn