|
This is a problem with your #include files, or a missing library. It can see the header for x1, but cannot find anything to link it to.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
"I'm thinking of getting married for companionship and so I have someone to cook and clean." - Martin Marvinski, 6/3/2002
|
|
|
|
|
|
It seems that you have the methods of your template class defined in .cpp file. You should move them to the header.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
You were right. I had the methods in a cpp file.
|
|
|
|
|
I tend to try things first to see if they work and ask why if they do not
std::string * pString = new std::string;
std::vector<int> * pInt = new std::vector<int>
The above compiles fine for me.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
"I'm thinking of getting married for companionship and so I have someone to cook and clean." - Martin Marvinski, 6/3/2002
|
|
|
|
|
Can anyone tell me what (obvious to everyone else) piece I'm missing? The following code doesn't work when run as a service. It runs fine when run through the IDE. All it does is set a timer. The SetTimer returns a valid number, but the TimerProc callback is never hit.
Any ideas?
Carl
///////////////////////////////////////////////////////////////////////////
[ module(SERVICE, uuid = "{99CCA443-725A-44F2-A5F3-9855AFACF970}",
name = "QService",
helpstring = "QService 1.0 Type Library",
resource_name="IDS_SERVICENAME") ]
class CQServiceModule
{
public:
CQServiceModule() {};
public:
HRESULT PreMessageLoop(int nShowCmd)
{
HRESULT hr = __super::PreMessageLoop(nShowCmd);
if ( SUCCEEDED(hr) )
return S_OK;
return hr;
}
HRESULT Start(int nCmd)
{
m_lTimer = (UINT)::SetTimer((HWND) NULL, 1,
10000, TimerProc);
return __super::Start(nCmd);
}
static void CALLBACK TimerProc(HWND hwnd,UINT uMsg, UINT idEvent,
DWORD dwTime)
{
_AtlModule.LogEvent(_T("TimerEvent"));
}
UINT m_lTimer;
};
|
|
|
|
|
AFAIK services do not have message loops - and message loop is required when you want to use SetTimer, even with a callback function.
Use Sleep() or waitable timer instead of SetTimer.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Thanks for the response.
The ATL service code includes 3 methods
PreMessageLoop();
RunMessageLoop();
PostMessageLoop();
Which lead me to think (incorrectly?) that this should work. It worked with the ATL code with version 6.0, although a lot of the code that had been explicitely generated before is now contained in CAtlServiceModuleT.
|
|
|
|
|
First, a service is a normal Windows 32 program, and as such it has at least a system message queue (even if it doesn't use it). Each thread may also have a thread specific message queue, but the creation is deferred until it's really needed (e.g., a User or GDI function is called). The old SetTimer function makes use of window messages (it was normally used for background processing purposes back in the 16-bit days), even if you specify a callback. Because of this reason, one must get and dispatch messages when it's used.
Basically, all you need to do is to implement a Get-or-Peek/DispatchMessage-loop somewhere in your ServiceMain (or a function called from it). This is what makes the wheel go round. MFC and other framework libraries have a message loop buried way down in their private code, so you don't see it often these days, but it's still integral to Windows.
However, if the only WM-based function you're going to be using is SetTimer, there is a better solution: Waitable Timers. A waitable timer is a kernel object that can be waited on using the WaitForXObject(s) set of functions (cf. CreateWaitableTimer API), and it can be set to an absolute or relative due time. This way you can combine it with waiting on other events such as a Quit event, which is a good service design.
|
|
|
|
|
Thank you for responding to my query. I always appreciate it when people take the time to help.
The Run() method in AtlServiceModule calls this method
void RunMessageLoop() throw()
{
MSG msg;
while (GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
and I have checked and made sure this is being hit.
As to only using a timer, my service is instantiating a COM object that uses WinSock messages (that weren't processed either). I have since written my own WinSock module that uses overlapped IO, but I am rather stubborn and would like to know WHY this code doesn't work. Timers worked fine in a service generated under VC6.
Again, I'd like to thank the people that have responded to my query. I posted the same question in a newsgroup and no one responded.
|
|
|
|
|
Where can I get a icon editor capable of XP icons, with other words, making antialiased icons...nice smooth corners...
Regards
Andreas Svensson
|
|
|
|
|
Adobe Illustrator
Jon Sagara
What about ?
Best Miniputt score: 21
Sonork ID: 100.9999 jonsagara
|
|
|
|
|
|
Photoshop works nicely i'm told. There is an add-in called IconBuilder specifically to support this. See http://www.iconfactory.com/ for more information.
And if words were wisdom, I'd be talking even more. The Offspring, I Choose
|
|
|
|
|
As most of you know when creating a popup menu, you use SetForegroundWindow....
If you create two Systray applications with popup menus using this command...the menu won't disappear if you open it and open the other one and then the first again..
It's stuck, it won't disappear since the menu doesn't seem to have the focus the second time you use SetForegroundMenu....
Not that serious but, it's a disturbing thing which creates problems with complex applications....
Windows own applications doesn't not have this problem, though the samples on the MSDN does.....
Please notify me if you know anything about this
Andreas Svensson - ICQ# 123883974
|
|
|
|
|
|
I'm trying to make my own assert and add some file logging. Looking at assert.h I see the following #define
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
I'm a little confused with that ,0 in there. What does that expression evaluate to?
The problem I'm having is, when I call _assert myself I get an abnormal program termination when I click on Ignore in the assert dialog.
Here's the ohter part of the header
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#ifdef __cplusplus
}
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
Todd Smith
CPUA 0x007 ... shaken not stirred
|
|
|
|
|
Todd Smith wrote:
I'm a little confused with that ,0 in there. What does that expression evaluate to?
This evaluates to zero. Generally, the value of (x,y) is y. For more info, search the help for 'comma operator'.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Then it appears that the Ignore button on the assert dialog does not work.
#include <assert.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
assert(false);
printf("ignore assert works!");
return 0;
}
That just exits when I click on Ignore. *sigh*
I guess I should be using _CrtDbgReport to assert instead.
Todd Smith
CPUA 0x007 ... shaken not stirred
|
|
|
|
|
Basically, you can ignore the 'Ignore' button.
It's probably there because there's only MB_ABORTRETRYIGNORE - you'll not find MB_ABORTRETRY.
_assert() calls abort() which aborts the program (Abort/Ignore) or transfers control to the debugger (Retry).
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
I'm tring to make a template class as follows:
template <class t=""> class x1 : public CWinThread
{
DECLARE_DYNCREATE(x1)
.
.
.
}
In the CPP file on the IMPLEMENT_DYNCREATE( x1, CWinThread) I get the following errors:
: error C2955: 'x1' : use of class template requires template argument list
: error C2512: 'x1<t>' : no appropriate default constructor available
I've tried a few things but cant get this thing to compile. Is it futile to try and make a template on an MFC class?
Thanks.
|
|
|
|
|
Sorry - DECLARE_xxx/IMPLEMENT_xxx are not suitable for templates. These macros use ## (token paste) preprocessor operator to declare a static member of your class which has a name like classCYourClass (assuming that you've used DECLARE_DYNAMIC(CYourClass)). This approach fails for templates - you can't have a C++ identifier with a name like 'classCYourClass<X>'
So you can derive a template class from MFC classes, but you have to give up DECLARE_xxx/IMPLEMENT_xxx - which is often painless.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
I'm writing an app that needs to know when someone logs on or logs off. I used GetSafeHwnd() to send WTSRegisterSessionNotification the window I was using. YOu can find all the info for it here http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/tsref_8d66.asp
Now they say I can use http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/tsref_7fvp.asp WM_WTSSESSION_CHANGE
to recieve the messages through the windowproc
LRESULT CALLBACK WindowProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
now, how in the world do I use this? I have absolutely no idea how to use this with windowproc
thx
I can imagine a world without war and hate, I can imagine us attacking that world because they'd never expect it.
|
|
|
|
|
This just means that your window will get WM_WTSSESSION_CHANGE. You pass its hwnd to WTSRegisterSessionNotification.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
I need to know how to get the messages when they are sent out, I can see what it does I just don't know how to get or when to get the message for the notification
I can imagine a world without war and hate, I can imagine us attacking that world because they'd never expect it.
|
|
|
|