SetTimer function in a dll file - c++

I'm writing a plugin for the musicplayer named MusicBee.
The plugin is for the Logitech G keyboards LCD.
Now I will look at buttons activity every 30ms so everyting is fast when pressing on it.
I will use the setTimer function of windows.h but I can't get it to work in my dll file.
Can someone help me with this little problem??
The code I have is (TimerProc function is a static function):
Logitech * Logitech::LogitechObject;
Logitech::Logitech(): stopthread(false), firstTime(true), position(0), duration(0)
{
LogitechObject = this;
SetTimer(NULL, 1, 30, &Logitech::TimerProc);
}
Logitech::~Logitech()
{
stopthread = true;
this->state = StatePlay::Undefined;
timerThread.detach();
}
VOID CALLBACK Logitech::TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
LogitechObject->time = 0;
LogitechObject->m_lcd.SetProgressBarPosition(LogitechObject->progressbar, static_cast<FLOAT>(100));
LogitechObject->m_lcd.Update();
SetTimer(NULL, 1, 30, &Logitech::TimerProc);
}

In order SetTimer to work the application should run "message pump" loop ( GetMessage()/DispatchMessage() ). Without it WM_TIMER message will not be delivered and so your TimerProc will not be invoked.
Use CreateTimerQueueTimer() instead.

Related

SendNotifyMessage do not send correct messages

From one thread I send the message to main thread in window procedure.
But it is unsuccessful. When I send messages from the same thread - all is ok
include "stdafx.h"
#include <Windows.h>
#include <atlbase.h>
#define MAX_THREADS 1
HWND m_wnd;
enum
{
EVENT_CALL = (WM_APP + 0x30),
};
static LRESULT CALLBACK function_call()
{
//some code
int test = 0;
return 0;
}
static LRESULT CALLBACK http_message_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case EVENT_CALL:
function_call();
return 0;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void CreateNotifyWnd()
{
WNDCLASSEX w = { 0 };
w.cbSize = sizeof(w);
w.hInstance = (HINSTANCE)&__ImageBase;
w.lpszClassName = L"uistone_http_event_wnd";
w.lpfnWndProc = http_message_proc;
::RegisterClassEx(&w);
int error = GetLastError();
m_wnd = ::CreateWindowEx(0, w.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, w.hInstance, 0);
error = GetLastError();
}
DWORD WINAPI SendThread(void* request_param)
{
::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);
int error = GetLastError();
return 0;
}
int main()
{
CreateNotifyWnd();
HANDLE hThreadArray[MAX_THREADS];
hThreadArray[0] = CreateThread(nullptr, 0, SendThread, nullptr, 0, nullptr);
//::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
return 0;
}
Why I can not catch messages from another thread?
Thanks.
This is documented behavior. This is the relevant part from the SendNotifyMessage documentation:
If the window was created by the calling thread, SendNotifyMessage calls the window procedure for the window and does not return until the window procedure has processed the message. If the window was created by a different thread, SendNotifyMessage passes the message to the window procedure and returns immediately; it does not wait for the window procedure to finish processing the message.
This appears to work when used with a window created on the same thread, because when you call SendNotifyMessage, the function synchronously calls into the window procedure associated with the target window before returning.
If the call crosses threads, on the other hand, you'd have to run a message loop for the - now queued - message to get picked up and passed to the window procedure1). Your application doesn't run a message loop, and it exits before the message ever reaches the target window.
To fix this you'd have to run a message loop. This may or may not be the right approach to your problem. Since we don't know, what problem you are trying to solve, we cannot suggest potentially superior approaches and solutions.
1) See About Messages and Message Queues: Message Routing.

C++ Animating a button with MoveWindow()

I am new to C++ and seem to be stuck. I basically have a Window and a Button inside it(also created with CreateWindow()). I want to have the button moving on the X axis, I tried doing with MoveWindow() but I cant seem to do the animation effect. I tried writing it in a for loop but I have not found what to use to delay the animation. I would appreciate any help.
for (int i = 0; i < 50; i++) {
MoveWindow(g_MovingDot, i, ButtonTop, ButtonWidth, ButtonHeight, true);
//Delay it somehow
}
Would this be the right way to do it? I just want the button to move slowly to the right.
Use the SetTimer function to be notified when the time-out value is elapse.
Implement a function with the signature
VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD);
and pass a function pointer to SetTimer, to register a callback procedure .
Use a global control variable, which controls the animation of the window. In the following code snippet the control variable is named i_g.
When the timer is elapsed, then the callback procedure is called. Increment the control variable, slightly move the dialog element and restart the timer, until the final position is reached.
The animation time is controlled by the number of animation steps and the time interval of a single step.
int g_i=0;
void CALLBACK BtnTimer( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
KillTimer( hwnd, idEvent );
if ( g_i < 50 )
{
MoveWindow(g_MovingDot, i, ButtonTop, ButtonWidth, ButtonHeight, true);
g_i ++;
SetTimer( hwnd, idEvent, 100 /* time milliseconds */, &BtnTimer );
}
}
void AnimateButton( HWND hDialogWnd //* HWND from Dialog */)
{
g_i = 0;
SetTimer( hDialogWnd, 0 /* idEvent */, 100 /* time milliseconds */, &BtnTimer );
}

C++ (press button 1, show bitmap "P", 2sec, hide bitmap "P")

I am using C++ , and I want to do this in a dialog box.
Press button 1, show bitmap "P", wait 2sec, hide bitmap "P", press button 1 again.....
void CPreparationDlg::OnBnClickedButton1()
{
GetDlgItem(IDC_P)->ShowWindow(SW_SHOW);
SetTimer(0, 2000, NULL);
GetDlgItem(IDC_P)->ShowWindow(SW_HIDE);
}
In this dialogbox I have do 4 buttons and 4 different pictures respectively.
The buttons are 1,2,3,4, pictures are IDC_P, IDC_L, IDC_E, IDC_K.
!!!!!
After I tried these code for button 1, the bitmap cannot be shown. I am only able to do is show, but it can't hide.
void CPreparationDlg::OnBnClickedButton1()
{
GetDlgItem(IDC_P)->ShowWindow(SW_SHOW);
}
void CPreparationDlg::OnBnClickedButton2()
{
GetDlgItem(IDC_L)->ShowWindow(SW_SHOW);
}
void CPreparationDlg::OnBnClickedButton3()
{
GetDlgItem(IDC_E)->ShowWindow(SW_SHOW);
}
void CPreparationDlg::OnBnClickedButton4()
{
GetDlgItem(IDC_K)->ShowWindow(SW_SHOW);
}
I have also tried these, but it underline the "IDC_P" in CALLBACK, and said it argument of type "int" is incompatible with parameter of type HWND
void CPreparationDlg::OnBnClickedButton1()
{
GetDlgItem(IDC_P)->ShowWindow(SW_SHOW);
UINT TimerId = SetTimer(0, 2000, &TimerProc);
}
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
GetDlgItem(**IDC_P**)->ShowWindow(SW_HIDE);
}
You could try:
void CPreparationDlg::OnBnClickedButton1()
{
GetDlgItem(IDC_P)->ShowWindow(SW_SHOW);
Sleep(2000);
GetDlgItem(IDC_P)->ShowWindow(SW_HIDE);
}
But this would halt your app until the 2 seconds are up.
You could also try using AfxBeginThread, or CreateThread to create a thread to do
this for you, so it doesn't halt your application.
But I think the most viable option would be to use a Windows timer as you have in your example, and handle WM_TIMER messages in the window procedure, not exactly well versed in how you'd go about that in MFC, but I hope this post was at least of some help to you.

C++ Console app, SetWindowsHookEx, Callback is never called

I have a little console application that has an embedded v8 engine, and I would like to add a hook to register key events. This all worked before when I was using Qt and QtScript, but I am porting it all over to straight C++ in VC++ 2008. The application compiles and runs, but the hook is never called, here is the relevant code:
In main()
HWND hwndC = GetConsoleWindow() ;
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE );
if (SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, hInst, NULL) == 0) {
printf("Failed to set hook\n");
} else {
printf("Hook established\n");
}
g->RunScript(argc,argv);
And the proc:
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
printf("HookProc called\n");
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);
if (wParam == WM_KEYDOWN) {
keyDown(p,g);
} else if (wParam == WM_KEYUP) {
keyUp(p,g);
}
fflush(stdout);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
This is essentially an expansion on shell.cc from the v8 sample code. I wonder if it is somehow blocking? I admit to not really knowing what I am doing here, just playing around and learning but this one has me stumped.
Inside of keyDown say, I have something like this:
v8::Handle<v8::String> callback_name = v8::String::New("onKeyDown");
v8::Handle<v8::Value> callback_val = g->_context->Global()->Get(callback_name);
if (!callback_val->IsFunction()) {
printf("No onKeyDown handler found\n");
return;
}
v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(callback_val);
const int argc = 1;
v8::Handle<v8::Value> argv[argc] = { v8::Int32::New(char(p->vkCode)) };
printf("Calling onKeyDown\n");
v8::Handle<v8::Value> result = callback->Call(g->_context->Global(), argc, argv);
Some of this may actually not work in the end, but it just never gets called, when I run the program, and define: onKeyDown = function(key) {...}; I can see that onKeyDown is working just fine, I can use all of my bound c++ method etc from JS, so this thing is just driving me batty.
Any help, maybe pointers to some educational materials would be much appreciated.
Just to be clear, this function in c: LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) is never getting called, or never seeing a printf, and the output at the start says: Hook established, so windows is reporting the hook is established.
/Jason
A low-level hook, like WH_KEYBOARD_LL requires that your application pumps a message loop. That's the only way that Windows can break into your thread and make the call to the HookProc callback you registered.
A console mode app doesn't pump a message loop like regular Windows GUI apps do. Judging from your snippet, it isn't going to be easy to add one either. You'll need to create a thread.
Maybe this function will be of help to you?
GetAsyncKeyState

Win32 function for scheduled tasks in C++

I have a function in C++ that needs to be called after a period of time and this task is repeated. Do you know any built-in function or sample code in Win32 or pthread?
Thanks,
Julian
How about SetTimer.
Create a wrapper function to use as the callback for set timer.
Wrapper function calls your function.
After your function finishes, wrapper function calls SetTimer again to re-set the timer.
Just as a side note, I hope that you aren't doing something in code which could be done via the OS. (I don't know enough about your requirements to say, but I thought I'd point it out).
Things such as task-scheduler (windows) are made for scheduling recurring tasks, and they often do a better job than hand-rolled solutions.
SetTimer!
An example:
#include <windows.h>
#include <stdio.h>
void CALLBACK scheduled_task_1 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_1 every half-second event");
}
void CALLBACK scheduled_task_2 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_2 every two seconds event");
}
void CALLBACK scheduled_task_3 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_3 24 hours event");
}
void messageLoop(void) {
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage( &msg );
}
int main(void)
{
while(true)
{
SetTimer (NULL, 0, 500, scheduled_task_1); /* every half-second */
SetTimer (NULL, 0, 2000, scheduled_task_2); /* every two seconds */
SetTimer (NULL, 0, 60*60*24*1000, scheduled_task_3); /* after 24 hours or 86400000 milliseconds */
messageLoop();
}
return 0;
}