Valhalla Legends Forums Archive | C/C++ Programming | FlashWindow

AuthorMessageTime
Eli_1
Me again ::)...

I'm making a program that lets the user input a window's title, and 'flash time', then creates a timer that flashes the window (like aim does when you get a message).

The problem is that timFlash() is never being called for some reason, even though my thread proccess that handles messages AND the timer are being created successfully (so it says anyway).

Here's the code:
[code]
#include <windows.h>
#include <winuser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int MAX_SIZE = 256;
long FLASH_INVERT = 1;

// Some ghetto constants
long defaultFlashTime = 500;
char defaultWindow[] = "Brood War";
//

// Variables
char input[256], windowName[256];
HWND windowHWnd;
long flashTime;
long timerID = 0;
//

VOID CALLBACK timFlash(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
   static bool first = false;
   if (first == false) {
      first = true;
      printf("%u%u%u%u\n", hwnd, uMsg, idEvent, dwTime);
   }

   FlashWindow(windowHWnd, FLASH_INVERT);
}

DWORD WINAPI handleMessages(LPVOID lpParameter) {
   MSG msg;

   printf("Thread proccess: lpParameter -> %u\n", lpParameter);
   while(GetMessage(&msg, 0, 0, 0) == TRUE)
      DispatchMessage(&msg);
   
   printf("Thread finished.\n");
   return 0;
}

int main() {
HWND hwnd;
HANDLE msgHandle = NULL;
DWORD handleParam = 1;
DWORD handleID = NULL;

   printf("Window Flash ---\n");
   printf("Creating a thread that will handle messages...\n");
   msgHandle = CreateThread(NULL, 0, handleMessages, &handleParam, 0, &handleID);
   if (msgHandle == NULL) {
      printf("Error creating thread!\n");
      return -1;
   }
   
   printf("Thread created -> %u, %u\n\n", msgHandle, handleID);
   Sleep(1000); // Give the thread time to start up :/

   while ( 1 ) {
      printf("Enter an exact window title ('default' to use default): ");
      fgets(input, MAX_SIZE, stdin);
      if (strlen(input) > 1) {
         input[ strlen(input) - 1 ] = 0;
         strcpy(windowName, input);
         if ( (strlen(windowName) >= 7) && (strcmp(windowName, "default") == 0) ) {
            printf("Using default: %s\n", defaultWindow);
            strcpy(windowName, defaultWindow);
         }

         windowHWnd = FindWindow(NULL, windowName);
         if (windowHWnd == 0) {
            printf("Window not found!\n");
            continue;
         } else {
            printf("Window found! Handle -> %u\n", windowHWnd);
            printf("Enter flash time (0 to use default): ");
            fgets(input, MAX_SIZE, stdin);
            if ( input[0] == '\n' )
               continue;

            input[ strlen(input) - 1 ] = 0;
            flashTime = atol(input);
            if (flashTime == 0)
               flashTime = defaultFlashTime;
            if (timerID != 0)
               KillTimer(hwnd, timerID);
            
            timerID = SetTimer(hwnd, 0, flashTime, &timFlash); // I think somethin is going wrong here
            if (timerID == 0) {
               printf("Error creating timer!\n");
               break;
            } else
               printf("Timer created -> flashTime: %u, timerID: %u\n", flashTime, timerID);
         }
      }
   }
   if (timerID != 0)
      KillTimer(hwnd, timerID);

   CloseHandle(msgHandle);
   printf("Closing.\n");
   return 0;
}
[/code]

Output:
[quote]
Window Flash ---
Creating a thread that will handle messages...
Thread created -> 20, 429982383

Thread proccess: lpParameter -> 6618620
Enter exact window title ('default' to use default): default
Using default: Brood War
Window found! Handle -> 892
Enter flash time: 500
Timer created -> flashTime: 500, timerID: 390
Enter exact window title ('default' to use default):
[/quote]

Any idea why this isn't working?

P.S. Sorry for my sudden binge of asking for help :/
April 2, 2004, 12:30 AM
Maddox
The first thing I see is that "HWND hwnd" is never initialized. You should probably do SetTimer(NULL, ...) instead of SetTimer(hwnd, ...) or set hwnd to NULL.

On a side note, this isn't a very descriptive title. Your topic relates to timers and not "FlashWindow."
April 2, 2004, 1:47 AM
Eli_1
[quote author=Maddox link=board=30;threadid=6130;start=0#msg53137 date=1080870443]
The first thing I see is that "HWND hwnd" is never initialized. You should probably do SetTimer(NULL, ...) instead of SetTimer(hwnd, ...) or set hwnd to NULL.
[/quote]
I initialized hwnd to NULL, but it still isn't working correctly.

[quote]
On a side note, this isn't a very descriptive title. Your topic relates to timers and not "FlashWindow."
[/quote]
Sorry about that, I'll try to be more descriptive next time.
April 2, 2004, 2:02 AM
Eli_1
I did some more testing on it, and I found out that when I take the GetMessage loop out of the thread and put it in my main function, it works flawlessly. Why is it that GetMessage() is never returning when it's in the thread?
April 6, 2004, 5:54 PM
Telos
I think more importantly we need to ask why youre using FlashWindow and a timer when you can use FlashWindowEx to handle timed flashing for you
April 6, 2004, 6:05 PM
Eli_1
Thanks for that info on FlashWindowEx, but do you know why GetMessage isn't returning when it's in a thread?
April 6, 2004, 6:06 PM
Telos
Unless youre creating a window with some invisible code and it magically has the hWnd 0 which I dont think is even possible GetMessage is not going to do you any good

You only need a message loop when you actually have a window that will be receiving the messages
April 6, 2004, 6:11 PM
Eli_1
Having the hwnd set to 0 has never created a problem before. That's also how MSDN's example does it.
April 6, 2004, 6:14 PM
Telos
Only if you have a window which you dont! A 0 to GetMessage means use any window belonging to the calling thread but you have no window! You need a window to call GetMessage on and you have NO WINDOW!

I hope this clears things up
April 6, 2004, 6:17 PM
Eli_1
I don't get what you mean I don't have a window. :'(

Does this mean I can't use GetMessage in a thread ever?
April 6, 2004, 6:23 PM
Telos
A window is one of those pretty things that Windows draws on your desktop when you start a program. Your program does not have one. If anything it creates a console which is not a window. You will not get window messages unless you create an actual window

It means (and listen closely) that you need to create a window before you call GetMessage
April 6, 2004, 6:25 PM
Eli_1
[quote author=Eli_1 link=board=30;threadid=6130;start=0#msg53716 date=1081274383]
I did some more testing on it, and I found out that when I take the GetMessage loop out of the thread and put it in my main function, it works flawlessly. Why is it that GetMessage() is never returning when it's in the thread?
[/quote]
I'm receiving WM_TIMER here, and all I'm using is a console. So what do you mean I'll never receive messages if I don't have a window?
April 6, 2004, 6:32 PM
Telos
[quote author=Eli_1 link=board=30;threadid=6130;start=0#msg53727 date=1081276331]
I'm receiving WM_TIMER here, and all I'm using is a console. So what do you mean I'll never receive messages if I don't have a window?
[/quote]

Wtf are you talking about? You arent receiving WM_TIMER anywhere. Look at your code. Do you ever see yourself testing for a WM_TIMER message? No because there is no window for you to receive messages in. If you specify a function to be called in SetTimer then the timer calls that function rather than sending WM_TIMER notifications to a window. This is what you are doing.
April 6, 2004, 6:39 PM
Eli_1
[quote author=Telos link=board=30;threadid=6130;start=0#msg53728 date=1081276754]
Wtf are you talking about? You arent receiving WM_TIMER anywhere. Look at your code. Do you ever see yourself testing for a WM_TIMER message? No because there is no window for you to receive messages in. If you specify a function to be called in SetTimer then the timer calls that function rather than sending WM_TIMER notifications to a window. This is what you are doing.
[/quote]

1.)Quote from MSDN:
[quote]
An application can also create a timer whose WM_TIMER messages are processed not by the main window procedure but by an application-defined callback function, as in the following code sample, which creates a timer and uses the callback function MyTimerProc to process the timer's WM_TIMER messages.
[/quote]
So I have to be receiving WM_TIMER or else my callback function would never get called with DispatchMessage().

2.) Where do I see myself testing for WM_TIMER? I don't need to test. If the message is WM_TIMER than my
[code]VOID CALLBACK timFlash(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);[/code] function will be called to proccess that message.


I just want to know why the god damn program works when the GetMessage loop is in one function, and why it doesn't work when it's in another.
April 6, 2004, 7:05 PM
Telos
Yet somehow it completely eludes you that you never set a window handle to get the message...
April 6, 2004, 7:16 PM
Skywing
You don't need a window to receive messages posted to the thread message queue, like PostThreadMessage does.

GetMessage will block execution until you receive a message. Therefore, if you never receive a message, you will block execution indefinitely.
April 6, 2004, 9:05 PM
Adron
edit: Skywing, you respond too fast.
April 6, 2004, 9:09 PM
Myndfyr
eww @ the aim chat that happened here today.
April 7, 2004, 1:30 AM

Search