C++ Timer not working? - c++

I'm trying to make a timer in c++. I'm new to c++. I found this code snippet
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
I put it in my global variables and it tells me
Error 1 error C2373: 'SetTimer' : redefinition; different type modifiers
I'm not sure what this means. Is there a more proper way to define a timer?
I'm not using mfc / afx
Thanks

You should call it like this:
void CALLBACK TimerProc(
HWND hwnd,
UINT uMsg,
UINT idEvent,
DWORD dwTime
)
{
//do something
}
SetTimer(NULL, NULL, 1000, TimerProc);
This would set a timer for 1 second and will call TimerProc when it expires. Read TimerProc MSDN here: http://msdn.microsoft.com/en-us/library/ms644907%28VS.85%29.aspx

That's not a function call -- that's a function declaration, which you are probably already #including from somewhere. What you need is the actual SetTimer call from your code.
Can you post your code where you're trying to set up the timer, and the function you want it to call when it triggers?

Related

Unhandled exception when calling a SetWindowLongPtr

void IronmanMap::CommandLine()
{
mode = 1;
InvalidateRect(storedhwnd, NULL, 1);
HWND hmmitem;
hmmitem = GetDlgItem(storedhwnd, ID_EDITBOX1);
backupproc = (WNDPROC)SetWindowLongPtr(hmmitem, GWLP_WNDPROC, (LONG)EditProc);
SetFocus(hmmitem);
}
When this function gets to the closing brace it says there is an unhandled exception.
That line of code should be:
backupproc = (WNDPROC)SetWindowLongPtr(hmmitem, GWLP_WNDPROC,(LONG_PTR)EditProc);
But Raymond is so fast! :)
Edit: Jonathon Potter comments above that there's a better way to do this (and it's Microsoft's recommended way). So please ignore the above and subclass your window like this:
SetWindowSubclass (hmmitem, EditProc, EditProcSubclassID, EditProcReferenceData);
Where:
EditProcSubclassID is a unique ID of your choice (just make one up).
EditProcReferenceData will be passed to EditProc whenever it is called. You can use this for anything you like (or just pass 0).
You then implement EditProc like this (note the two extra parameters on the end there):
LRESULT CALLBACK EditProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
...
}
So what happened to backupproc? Well, you don't need that anymore. Instead, to call the next WndProc in the chain, call DefSubclassProc() (or not, if you want to swallow the message) at the end of EditProc.
Finally, if you want to detach EditProc from the window, call RemoveWindowSubclass().
The main advantage of this approach is that it works correctly if somebody else subclasses the window after you do (or, indeed, before, if they want to remove their WndProc before you do). That's why you should use it.
Read the SetWindowSubclass documentation on MSDN, and see Raymond's blog on Safer subclassing.

SetTimer Function on CWinApp failing to be set

I am currently making a C++ MFC application, and I need a timer to call a function called OnTimer every 30 seconds or so. Right now, I have a class that looks like this:
class CMyApp : public CWinApp
{
// Do some stuff...
DECLARE_MESSAGE_MAP()
BOOL InitInstance()
{
// m_pMainWnd is an object in CWinApp that allows me to render a window
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
// Do some stuff with this window
::SetTimer(NULL, 0, 30000, 0);
}
afx_msg void OnTimer(WPARAM wParam, LPARAM lParam)
{
// I want this function to execute every 30 seconds
// This function manipulates the window
}
}
BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
ON_THREAD_MESSAGE(WM_TIMER, OnTimer)
END_MESSAGE_MAP()
CMyApp theApp;
This method does get OnTimer to be called, but not every 30 seconds. In fact, OnTimer seems to get called hundreds of times a minute now. My question is: how do I set my class's timer?
Things I've tried
I've tried changing the user extension from ON_THREAD_MESSAGE to ON_WM_TIMER, to ON_COMMAND, and to ON_MESSAGE. For anything that isn't ON_THREAD_MESSAGE, I get the error
error C2440: 'static_cast' : cannot convert from 'void (__thiscall CMyApp::* )(WPARAM,LPARAM)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
I'm not sure, but I think SetTimer may be manipulating some CWinApp specific function, while the CWnd SetTimer is not being manipulated, and is set to some default value. I'm pretty much in the dark here though, any help would be appreciated.
ON_THREAD_MESSAGE is for user defined messages, not WM_TIMER
According to SetTimer documentation, the window handle must be valid, and the timer identifier must be non-zero to create a new timer. Example:
::SetTimer(m_pMainWnd->m_hWnd, 1, 30000, NULL);
or
m_pMainWnd->SetTimer(1, 30000, NULL);
The message can be handled in main GUI Window. For example CMainFrame, CMyCMDIFrameWnd, or whatever m_pMainWnd points to.
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_WM_TIMER()
...
END_MESSAGE_MAP()
void CMainFrame::OnTimer(UINT id)
{
TRACE("OnTimer(%d)\n", id);
}
Alternatively you can use NULL for window handle in ::SetTimer but you must supply a call back function:
VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
TRACE("TimerProc\n");
}
::SetTimer(NULL, 2, 30000, TimerProc);

Do CustomDialogProc have to be static. WinAPI

I've been looking at creating a custom control with WinApi for my application, and I have made a class which contains the CustomDialogProc and CreateWindowEx and RegisterClass() functions.
I can set a breakpoint inside the CustomDialogProc and it hits, so the class is registered correctly.
However, I have to declare the CustomDialogProc function as static int he header of my class
static LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam);
If I don't set it to static, I get the error
Error C3867 'CustomControl::CustomDialogProc': non-standard syntax; use '&' to create a pointer to member
IS this necessary, this requires all my controls created within this control to be static as well. What if I want multiple instances of this control?
How can I get around this? The main MsgProc doesn't seem to be a static function. Neither is the UpDownDialogProc in the first link shown below
Below is my code for CustomControl.h in case anyone needs it.
Put together from code found at:
https://msdn.microsoft.com/en-us/library/windows/desktop/hh298353(v=vs.85).aspx
https://www.codeproject.com/Articles/485767/True-Windows-control-subclassing
Thanks,
#pragma once
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")
class CustomControl
{
public:
CustomControl();
~CustomControl();
LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
//DO STUFF HERE
break;
}
}
bool CreateControl(HWND hwnd, HINSTANCE* m_hApp_instance)
{
g_hInst = m_hApp_instance;
RegisterSubClass(*g_hInst, WC_LISTBOX, TEXT("CustomControl"), CustomDialogProc);
HWND hwndCustom = CreateWindow(TEXT("CustomControl"), NULL, WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hwnd, (HMENU)100, *g_hInst, NULL);
return true;
}
private:
HINSTANCE* g_hInst;
WNDPROC RegisterSubClass(HINSTANCE hInstance, LPCTSTR ParentClass, LPCTSTR ChildClassName, WNDPROC ChildProc) {
WNDCLASSEX twoWayStruct;
WNDPROC parentWndProc;
if (GetClassInfoEx(NULL, ParentClass, &twoWayStruct)) {
parentWndProc = twoWayStruct.lpfnWndProc; // save the original message handler
twoWayStruct.cbSize = sizeof(WNDCLASSEX); // does not always get filled properly
twoWayStruct.hInstance = hInstance;
twoWayStruct.lpszClassName = ChildClassName;
twoWayStruct.lpfnWndProc = ChildProc;
/* Register the window class, and if it fails return 0 */
if (RegisterClassEx(&twoWayStruct))
return parentWndProc; // returns the parent class WndProc pointer;
// subclass MUST call it instead of DefWindowProc();
// if you do not save it, this function is wasted
}
return 0;
}
};
The most common way is to use SetWindowLongPtr to store a pointer to the object associated with the window handle.
HWND hWnd = CreateWindow(...);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) this);
And then in your dialog proc, get that pointer and call into your class:
// this static method is registered with your window class
static LRESULT CALLBACK CustomDialogProcStatic(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
auto pThis = (CustomControl*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (pThis != NULL)
return pThis->CustomDialogProcInstance(hWnd, uMsg, wParam, lParam);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// this instance method is called by the static method
LRESULT CustomDialogProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
}
Make sure you manage your window and class life cycle appropriately to prevent the window proc from calling a deleted object instance. In many cases, this is as simple as ensuring DestroyWindow is called if your class is destructed.
The Windows API is C language based. It knows nothing about C++, non-static member functions, objects, etc.
So yes, all of your functions that will communicate with the Windows API directly must be static class member functions, or non-class / global / "free" functions.
That doesn't preclude you from writing a C++ wrapper for a C API. That's what libraries such as Microsoft's MFC or the old Borland OWL libraries accomplish. Other independent groups have also written wrappers for the Windows API.
Note that these differing libraries accomplish the goal of hooking a C based API to C++ in different ways. One is to use the SetWindowLongPtr method mentioned in the answer given by #MichaelGunter. Another method is to use maps to associate window handles and static Window procedures.
I would suggest before you try this on your own (creating a wrapper), you investigate how others have done this already, and choose the best approach that fits. Another suggestion is that before you even create a wrapper, you should know the C based API on much more than a cursory level. You need advanced to expert knowledge of any C API you plan to create a C++ wrapper for if you want the wrapper to work relatively flawless under different scenarios.

WinApi SetTimer cannot compile

I need timer to start function every 1 second.
I have tried SetTimer, my code:
const UINT_PTR TIMER_ID = 1000;
DWORD DownloadThread()
{
SetTimer(NULL, TIMER_ID, 1000, (TIMERPROC)DownloadSpeedCounter);
/*some stuff*/
}
void DownloadSpeedCounter()
{
/*some stuff*/
}
I cannot compile this code and get error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'TIMERPROC'
Also it is class member method.
This is because you are trying to use a normal function as an application-defined callback function. What you are probably looking for is this application-defined callback function which could look like this:
VOID CALLBACK DownloadSpeedCounter(
HWND hwnd, // handle to window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime) {
/* some stuff */
}
For additional information on using callback functions for timers see this article.
One of the problems is that TIMERPROC functions should look like this: typedef VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD); So your method definition should look like this:
VOID CALLBACK DownloadSpeedCounter(HWND, UINT, UINT_PTR, DWORD);
Also, as this is a method, not just a function, it must be static. So it is calling like static but to access private non-static data may be used this technique.

Subclassing an edit control from a user defined class/pointer-to-member-function

I think I've fallen in the same trap as many before me where I try to impose a nice OO methodology on win32 API programming. No MFC, no AFX, I'm not even using VC++, I'm using C::B with gcc.
I think what I'm trying to do is impossible, but since MFC exists (although I'm not using it) there must be some way.
I've created a class to contain several window controls. It implements handlers for WM_CREATE and WM_COMMAND, and keeps track of all the associated data around my small group of controls (ID codes and HWNDs).
It works great for buttons, static controls, even light GDI methods, but it all breaks down when I try to subclass an edit control.
Really, I just want to capture the "enter" key, but as anybody who's been down that road before will attest, when an edit control has focus, the parent window doesn't receive WM_KEYDOWN or WM_COMMAND, we are left to implement our own proc. Super lame.
OK, so subclassing an edit control is fine, if the editProc is global or static. I know that is because SetWindowLongPtr needs a function address, and that concept is nebulous for a member function.
So the object of my class is declared as "static" inside the parent WndProc. But the function is not "static" because then I wouldn't have access to non-static data members (completely defeating the purpose of this exercise). I'm hoping that because the objest is itself static, I should be able to properly define the address of one of its member functions.
Readers that have tried this before will either have given up and used MFC or something else, or perhaps have found a clever work-around.
I'll let this sample code do the rest of the talking: (simplified - will not compile as such)
/**** myprogram.c ****/
#include "MyControlGroup.h"
int winMain(){ // etc... }
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// object is static becuse it only needs to be initialized once
static MyControlGroup myControl;
if (msg == WM_CREATE)
myControl.onWMCreate(hWnd);
else if (msg == WM_COMMAND)
myControl.onWMCommand( wParam, lParam );
else if (msg == WM_DESTROY)
PostQuitMessage(0);
return DefWindowProcW(l_hWnd, l_msg, l_wParam, l_lParam);
}
The header file for my class:
/**** MyControlGroup.h ****/
class MyControlGroup
{
private:
HWND m_hWndParent;
HWND m_hWndEditBox;
int m_editBoxID;
public:
MyControlGroup();
void onWMCreate(HWND);
void onWMCommand(WPARAM, LPARAM);
// want to find a way to pass the address of this function to SetWindowLongPtr
LRESULT myEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
...and the implementation:
/**** MyControlGroup.cpp ****/
static int staticID = 1;
MyControlGroup::MyControlGroup()
{
m_editBoxID = staticID++;
}
void MyControlGroup::onWMCreate(HWND hWnd)
{
// My control group has buttons, static controls, and other stuff which are created here with CreateWindowW. It also has an edit control:
m_hWndEditBox = CreateWindowW(L"EDIT", L"initial text", WS_CHILD | WS_VISIBLE | WS_BORDER, 10, 10, 150, 20, hWnd, (HMENU)m_editBoxID, NULL, NULL);
/*
To subclass the edit control, I need a pointer to my customized proc. That means I
need a pointer-to-member-function, but SetWindowLongPtr needs a pointer to global or
static function (__stdcall or CALLBACK, but not __thiscall).
*/
// I'd like to do something like this, adapted from a great write-up at
// http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
LERSULT (MyControlGroup::*myEditProcPtr)(HWND, UINT, WPARAM, LPARAM);
myEditProcPtr = &MyControlGroup::myEditProc;
// Up to now it compiles ok, but then when I try to pass it to SetWindowLongPtr, I get
// an "invalid cast" error. Any ideas?
SetWindowLongPtr(m_hWndEditBox, GWLP_WNDPROC, (LPARAM)myEditProcPtr);
}
void MyControlGroup::onWMCommand(WPARAM wParam, LPARAM lParam){ /* process parent window messages. Editboxes don't generate WM_COMMAND or WM_KEYDOWN in the parent :''( */}
LRESULT MyControlGroup::myEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// process messages like IDOK, WM_KEYDOWN and so on in the edit control
}
Even once I get this done, I'll still need to figure out a way to pass the address of the parent WndProc to myEditProc for the return value, but until I get past this there is no point in worrying about that.
Thanks in advance for reading!
myEditProc needs to be a static function.
Once you've done that you can pass the address of the function directly without going through the intermediate variable:
static LRESULT myEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
...
SetWindowLongPtr(m_hWndEditBox, GWLP_WNDPROC, (LPARAM)myEditProc);
To access your class data from the static function, you can save it in the userdata field of the edit control, e.g.:
// before sub-classing the control
SetWindowLongPtr(m_hWndEditBox, GWLP_USERDATA, (LPARAM)this);
// in the sub-class procedure
MyControlGroup* pThis = (MyControlGroup*)GetWindowLongPtr(m_hWndEditBox, GWLP_USERDATA);
But as #K-ballo suggested, SetWindowSubclass is definitely the way to do this unless you want compatibility with pre-XP. It handles the sub-classing procedure for you automatically, lets you associate a userdata pointer (e.g. this) that is automatically passed to the sub-class procedure, and safely handles removing the sub-class at the end.