Thread View: borland.public.cppbuilder.nativeapi
10 messages
10 total messages
Started by poojo hackma
Mon, 12 Feb 2007 20:21
Getting Message with WinMain
Author: poojo hackma
Date: Mon, 12 Feb 2007 20:21
Date: Mon, 12 Feb 2007 20:21
12 lines
1481 bytes
1481 bytes
I've got a small AutoRun style application that currently only has a WinMain function (i.e. old C program style). How can I add the ability to search for Windows Messages like WM_COMMAND? TCustomForm includes a WndProc function that has what I want, but my small WinMain application does not have (or need) a TForm. Is there some way to implement this without having to create a form that I don't use? Or, how would I create a custom WndProc for my application? Thanks in advance! PJ
Re: Getting Message with WinMain
Author: Remy Lebeau (TeamB)
Date: Mon, 12 Feb 2007 20:34
Date: Mon, 12 Feb 2007 20:34
33 lines
2088 bytes
2088 bytes
"poojo hackma" <poojo.com/mail> wrote in message news:45d0cc1f@newsgroups.borland.com... > I've got a small AutoRun style application that currently only > has a WinMain function (i.e. old C program style). > > How can I add the ability to search for Windows Messages like WM_COMMAND? First, you need an actual window to receive the message with. Console applications do not have a window by default. You will have to call CreateWindow/Ex() for that. Second, you need an active message queue to receive and process messages with. You will have to call Get/PeekMessage(), TranslateMessage(), and DispatchMessage() for the lifetime of the program for that. > TCustomForm includes a WndProc function that has what I want, but > my small WinMain application does not have (or need) a TForm. Is there > some way to implement this without having to create a form that I don't use? If you have enabled the VCL for your project, then you can use the AllocateHWnd() function instead of calling CreateWindow/Ex(). The callback method for AllocateHWnd() has to be a member of a class, and you still need to implement your own message queue to receive the messages. Gambit
Re: Getting Message with WinMain
Author: poojo hackma
Date: Mon, 12 Feb 2007 22:29
Date: Mon, 12 Feb 2007 22:29
91 lines
3871 bytes
3871 bytes
Thanks Gambit,
I've been chugging through the Help with the info you gave me, but now I am
stuck.
Here is why:
CreateWindow requires lpClassName, which can be an ATOM.
RegisterClass() creates an ATOM, but requires a WNDCLASS parameter.
The WNDCLASS structure requires lpClassName.
Now I am stuck in a loop.
I am trying to pop up a notification icon in the taskbar.
What did I missunderstand?
Code: (not all of the variables have been shown)
//---------------------------------------------------------------------------
void Say(const wchar_t* message, wchar_t* title) {
#ifdef _DEBUG
wchar_t *clob = title;
wcscat(clob, L"\n");
wcscat(clob, message);
MessageBox(NULL, message, L"Debug", MB_OK);
#endif
}
//---------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR
lpCmdLine, int nCmdShow) {
if (SHGetAutoRunPath(Path) == FALSE) {
Say(L"No AutoRun path. Exiting.", L"WinMain");
return 0; // no CF card detected. Exit
} else if (IsProcessRunning(L"wceload.exe") == TRUE) { // exit!
Say(L"Process Is Running. Exiting.", L"WinMain");
return 0;
} else {
wcscpy(buff, Path);
wchar_t *c;
c = buff;
buffTail = c;
while (*c != 0) {
if (*c == '\\')
buffTail = c + 1;
c++;
}
}
wchar_t *cmdLine;
wchar_t *exeFile = L"App1.exe"; // Main executable file
wchar_t *cabFile = L"App1.ARM.CAB"; // CAB file for Main setup
wchar_t *strKey = L"SOFTWARE\\Apps\\LU App1";
wchar_t *str404 = L"File Not Found";
SHNOTIFICATIONDATA nd = {0};
HICON hIcon = NULL;
#ifdef _DEBUG
if (1) {
#else
if (lstrcmpi(lpCmdLine, _T("install")) == 0) { // Card has been inserted
#endif
DWORD dwStyle = WS_HSCROLL | WS_VSCROLL;
wchar_t *szClass = L"TSpongeBob";
wchar_t *szWindow = L"SquarePants";
ATOM atom = GlobalAddAtom(szClass); // the OS did not like SpongeBob!
hNdWnd = CreateWindowEx(0, szClass, szWindow, dwStyle,
0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, AfxGetInstanceHandle(), (LPVOID)&lParam);
cmdLine = BuildCmdLine(exeFile);
nd.dwID = dwID;
nd.clsid = guid;
nd.npPriority = SHNP_INFORM;
nd.csDuration = 20;
nd.hwndSink = hNdWnd;
nd.hicon = ExtractIconEx(cmdLine, 0, NULL, &hIcon, 1);
nd.cbStruct = sizeof(SHNOTIFICATIONDATA);
nd.pszTitle = szTitle;
if (FileExists(cmdLine) == TRUE) {
wsprintf(htmlBuf, szFormat, szHtmLink, szTitle,
szHtmMsg, szInputYes, szInputNo);
nd.pszHTML = htmlBuf;
nd.lParam = lParam;
return SHNotificationAdd(&nd);
// next, I need a way to capture IDYES or IDNO
}
}
return 0;
}
//---------------------------------------------------------------------------
EOF
Re: Getting Message with WinMain
Author: Remy Lebeau (TeamB)
Date: Mon, 12 Feb 2007 23:24
Date: Mon, 12 Feb 2007 23:24
196 lines
6975 bytes
6975 bytes
"poojo hackma" <poojo.com/mail> wrote in message
news:45d0ea45$1@newsgroups.borland.com...
> CreateWindow requires lpClassName, which can be an ATOM.
>
> RegisterClass() creates an ATOM, but requires a WNDCLASS parameter.
>
> The WNDCLASS structure requires lpClassName.
>
> Now I am stuck in a loop.
You did not read the documentation for CreateWindow() carefully
enough:
lpClassName
Points to a null-terminated string or is an integer atom. If this
parameter is an atom, it must be a global atom created by a previous
call to the GlobalAddAtom function. The atom, a 16-bit value less than
0xC000, must be in the low-order word of lpClassName; the high-order
word must be zero.
If lpClassName is a string, it specifies the window class name.
The class name can be any name registered with the RegisterClass
function or any of the predefined control-class names. For a complete
list, see the following Remarks section. "
So, in this case, you would specify your own class name string in the
WNDCLASS structure, and then pass that same string value to
CreateWindow(). Do not use atoms at all. You need to use WNDCLASS so
that you can register a window procedure to handle the messages.
> I am trying to pop up a notification icon in the taskbar.
Creating a window is a separate operation from adding icons to the
System Tray. The only reason to have a window is if you want to
respond to user actions on the icon, such as mouse clicking.
> wchar_t *clob = title;
> wcscat(clob, L"\n");
> wcscat(clob, message);
> MessageBox(NULL, message, L"Debug", MB_OK);
That can be very dangerous code. You are appending your message
string to a buffer that you do not know the size of. Worse, you are
passing string literals when calling Say(), so you are actually trying
to alter static memory, which is likely to crash the program.
Besides, you are not even using clob for anything, so just get rid of
it altogether, ie:
void Say(const wchar_t* message, const wchar_t* title)
{
#ifdef _DEBUG
MessageBox(NULL, message, title, MB_OK);
#endif
}
Now, with that said, I see you using a lot of wchar_t buffers and
literals, but you are calling APIs that can be defined as either Ansi
or Unicode. You should use Microsoft's TCHAR and LPTSTR defines to
make your code more portable. Try this instead:
void Say(LPCTSTR message, LPCTSTR title)
{
#ifdef _DEBUG
MessageBox(NULL, message, title, MB_OK);
#endif
}
LRESULT CALLBACK SpongeBobWindowProc(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM lParam)
{
// process messages as needed ...
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
if( SHGetAutoRunPath(Path) == FALSE )
{
Say(TEXT("No AutoRun path. Exiting."), TEXT("WinMain"));
return 0; // no CF card detected. Exit
}
if( IsProcessRunning(TEXT("wceload.exe")) == TRUE)
{
// exit!
Say(TEXT("Process Is Running. Exiting."),
TEXT("WinMain"));
return 0;
}
LPTSTR c = Path;
buffTail = c;
while( *c != 0 )
{
if( *c == TEXT('\\') )
{
buffTail = CharNext(c);
c = buffTail;
}
else
c = CharNext(c);
}
LPTSTR cmdLine;
LPTSTR exeFile = TEXT("App1.exe"); // Main executable
file
LPTSTR cabFile = TEXT("App1.ARM.CAB"); // CAB file for Main
setup
LPTSTR strKey = TEXT("SOFTWARE\\Apps\\LU App1");
LPTSTR str404 = TEXT("File Not Found");
WNDCLASS cls = {0};
cls.lpfnWndProc = SpongeBobWindowProc;
cls.hInstance = hInstance;
cls.lpszClassName = TEXT("TSpongeBob");
if( !RegisterClass(&cls) )
{
// exit!
Say(TEXT("Cannot register sink window. Exiting."),
TEXT("WinMain"));
return 0;
}
hNdWnd = CreateWindowEx(0, cls.lpszClassName, NULL, 0, 0, 0,
0, 0, NULL, NULL, hInstance, &lParam);
if( !hNdWnd )
{
// exit!
Say(TEXT("Cannot create sink window. Exiting."),
TEXT("WinMain"));
return 0;
}
cmdLine = BuildCmdLine(exeFile);
#ifndef _DEBUG
if( lstrcmpi(lpCmdLine, TEXT("install")) == 0 )
{
// Card has been inserted
SHNOTIFICATIONDATA nd = {0};
HICON hIcon = NULL;
nd.cbStruct = sizeof(SHNOTIFICATIONDATA);
nd.dwID = dwID;
nd.clsid = guid;
nd.npPriority = SHNP_INFORM;
nd.csDuration = 20;
nd.hwndSink = hNdWnd;
nd.hicon = ExtractIconEx(cmdLine, 0, NULL, &hIcon, 1);
nd.pszTitle = szTitle;
if( FileExists(cmdLine) == TRUE )
{
wsprintf(htmlBuf, szFormat, szHtmLink, szTitle,
szHtmMsg, szInputYes, szInputNo);
nd.pszHTML = htmlBuf;
nd.lParam = lParam;
if( SHNotificationAdd(&nd) != ERROR_SUCCESS )
{
// exit!
Say(TEXT("Cannot add notification icon.
Exiting."), TEXT("WinMain"));
DestroyWindow(hNdWnd);
UnregisterClass(cls.lpszClassName, hInstance);
return 0;
}
}
}
#endif
MSG msg;
while( GetMessage(&msg, 0, 0, 0) > 0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hNdWnd);
UnregisterClass(cls.lpszClassName, hInstance);
return 0;
}
Gambit
Re: Getting Message with WinMain
Author: Bob Gonder
Date: Tue, 13 Feb 2007 15:46
Date: Tue, 13 Feb 2007 15:46
28 lines
1832 bytes
1832 bytes
poojo hackma wrote:
> nd.pszTitle = szTitle;
> if (FileExists(cmdLine) == TRUE) {
> wsprintf(htmlBuf, szFormat, szHtmLink, szTitle,
> szHtmMsg, szInputYes, szInputNo);
> nd.pszHTML = htmlBuf;
> nd.lParam = lParam;
> return SHNotificationAdd(&nd);
> // next, I need a way to capture IDYES or IDNO
That all seems a rather complex way (even the correct way as Remy
shows) of doing what I think you are trying to do:
wsprintf( htmlBuf, szFormat, szHtmLink, szTitle,
szHtmMsg, szInputYes, szInputNo);
switch( MessageBox( NULL, htmlBuf, szTitle, MB_YESNO |
MB_ICONQUESTION ) )
{
case IDYES:
// do whatever "yes" needs doing
break;
case IDNO:
// do the "no" thing
break;
//case IDCANCEL:
};;
Re: Getting Message with WinMain
Author: poojo hackma
Date: Tue, 13 Feb 2007 17:40
Date: Tue, 13 Feb 2007 17:40
26 lines
2264 bytes
2264 bytes
Thanks Gambit.
Wow, that's good stuff. I was sure there was a way out of my loop dilemma,
but the functions were all new to me. Determining the proper way to use them
together was posing a riddle. LOL
I've never come across CharNext or DefWindowProc, but they are in my
"Bag-O-Tricks" now. :)
I modified my Say function to prevent altering static memory. I probably
would have realized that had I looked closely enough at it.
As you've probably guessed, this is a Windows CE application. That was why I
declared everything as wchar_t, but you are right: The code is more portable
with TCHAR.
Let me ask this: Why do most people use TEXT("This is text") instead of
L"This is text"?
Having my little pinky hold down the shift key while I type just seems a
little like busy work, but there may be portability reasons that I'm not
aware of. My help says TEXT is a macro for the "L" version. I just want to
make sure I'm not missing something.
Regards,
PJ
Re: Getting Message with WinMain
Author: Remy Lebeau (TeamB)
Date: Tue, 13 Feb 2007 17:53
Date: Tue, 13 Feb 2007 17:53
16 lines
1675 bytes
1675 bytes
"poojo hackma" <poojo.com/mail> wrote in message
news:45d1f7ef@newsgroups.borland.com...
> Why do most people use TEXT("This is text") instead of L"This is
text"?
Using 'L' forces the compiler to generate the string literal as a
wchar_t* string. Using the TEXT() or _T() macros instead allows the
string literal to be either char* or wchar_t* depending on whether the
project is compiled for Unicode or not. Same with the TCHAR and
LPTSTR macros - they map to either char or wchar_t accordingly as
well. That is the portability that I was referring to earlier.
Gambit
Re: Getting Message with WinMain
Author: Remy Lebeau (TeamB)
Date: Tue, 13 Feb 2007 17:56
Date: Tue, 13 Feb 2007 17:56
14 lines
1484 bytes
1484 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message news:qgm3t2la0698dmq9dfvpffjha7pvv4uc7s@4ax.com... > That all seems a rather complex way (even the correct way > as Remy shows) of doing what I think you are trying to do: The code is not doing what you think it is doing. SHNotificationAdd() is Windows CE's equivilent to Shell_NotifyIcon(). Both functions put a notification icon into the System Tray. SHNotificationAdd() has different options than Shell_NotifyIcon(), though. Gambit
Re: Getting Message with WinMain
Author: Alan Bellingham
Date: Wed, 14 Feb 2007 10:12
Date: Wed, 14 Feb 2007 10:12
25 lines
2305 bytes
2305 bytes
"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote: >Using 'L' forces the compiler to generate the string literal as a >wchar_t* string. Using the TEXT() or _T() macros instead allows the >string literal to be either char* or wchar_t* depending on whether the >project is compiled for Unicode or not. Same with the TCHAR and >LPTSTR macros - they map to either char or wchar_t accordingly as >well. That is the portability that I was referring to earlier. IMAO, this portability is a false god - it clutters up your source code with all sorts of junk for no benefit. Far better just to write it for Unicode. Or if Unicode is inappropriate, then write it for 'Ansi' (MBCS). Trying to write for both, though, is a mess. (Yes, I'm currently stripping all this crud out of my source code - how did you guess? I'd love for the standard to support a compiler flag so that even the L"" wasn't required (perhaps needing S"" instead for octet char strings)). Your opinion is obviously different. Alan Bellingham -- 10th Anniversary ACCU Conference: 11-14 April 2007 - Oxford, UK (Booking now open: see http://accu.org/index.php/conferences for details)
Re: Getting Message with WinMain
Author: Remy Lebeau (TeamB)
Date: Wed, 14 Feb 2007 10:50
Date: Wed, 14 Feb 2007 10:50
20 lines
1877 bytes
1877 bytes
"Alan Bellingham" <alan@lspace.org> wrote in message news:4rn5t2h81tkf5pev5otv3pip3rk5b5c2qr@4ax.com... > IMAO, this portability is a false god - it clutters up your source > code with all sorts of junk for no benefit. No, it doesn't. And yes, there is a benefit. > Far better just to write it for Unicode. Or if Unicode is inappropriate, > then write it for 'Ansi' (MBCS). Trying to write for both, though, is a mess. Not really. When the macros are used properly, you can then toggle a single define in one place and have everything switch from char* to wchar_t* and back automatically without any code changes. Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads