• Welcome to Valhalla Legends Archive.
 

FlashWindow

Started by Eli_1, April 01, 2004, 06:30 PM

Previous topic - Next topic

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:

#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;
}


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):

Any idea why this isn't working?

P.S. Sorry for my sudden binge of asking for help :/

Maddox

#1
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."
asdf.

Eli_1

Quote from: Maddox on April 01, 2004, 07:47 PM
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.
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."
Sorry about that, I'll try to be more descriptive next time.

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?

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

Eli_1

Thanks for that info on FlashWindowEx, but do you know why GetMessage isn't returning when it's in a thread?

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

Eli_1

Having the hwnd set to 0 has never created a problem before. That's also how MSDN's example does it.

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

Eli_1

#9
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?

Telos

#10
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

Eli_1

Quote from: Eli_1 on April 06, 2004, 12:59 PM
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?
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?

Telos

Quote from: Eli_1 on April 06, 2004, 01:32 PM
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?

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.

Eli_1

#13
Quote from: Telos on April 06, 2004, 01:39 PM
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.

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.
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
VOID CALLBACK timFlash(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); 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.

Telos

Yet somehow it completely eludes you that you never set a window handle to get the message...