Progress Bar with DialogBox....detecting COM Ports...>"<..help~~

Hi,

I got this problem and I'm stucking with those codes seems forever~~  So help me~~

Here is my problem...

I got three main functions in order to detecting COM Ports and show the progress.
1. MainFunc:
In this function, first I call CreateThread like the following
  DlgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE )ProgressDlg, NULL, 0, &ThreadID);

  if (DlgThread != NULL)
      CloseHandle(DlgThread);
Then, I continue doing the detecting part with some for-loops...
While doig these loops, I use "SendMessage(hwndPB, PBM_STEPIT, 0, 0);"...according to their percentage..of course...to update the progress...

2. ProgressDlg...
In this function, I use "DialogBox(hInst, (LPCSTR)IDD_DetectProgress, gHwnd, ProgressDlgProc);"

3.  ProgressDlgProc
    switch(message)
    {
          case WM_INITDIALOG:
                        hwndDlg = hDlg;
                        hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                        SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
                        SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);
                  return 0;
    }


********************************************************************

These functions work fine for the first detecting...but the second time I call these function again...it seems like it will stuck in "ProgressDlg" (the part of DialogBox)...So in the MainFunc, SendMessage and EndDialog cannot have the right value for the handle part...so what's wrong with my codes?  What should I do to make my codes works fine??  Help~~~  Help~~~  >"<

Xenia

xenia27Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Roshan DavisCommented:
Are you calling any dialog specific functions from thread (instead of posting messages..)...?

If you, change that to PostMessage

Rosh L)
0
xenia27Author Commented:
I don't understand what you mean...>"<  Sorry~
The thread...basically only execute the function "ProgressDlg"...and which will call "DialogBox" and "ProgressDlgProc"....and I didn't do anything else at all...>"<


Xenia
0
AlexFMCommented:
I don't see handling of PBM_STEPIT message. I don't see here where dialog is created, where worker thread is created. A lot of important information is missing in your post, and it is very difficult to find the problem. Even description of the problem itself:
>>...it seems like it will stuck in "ProgressDlg" (the part of DialogBox)...So in the MainFunc, SendMessage and EndDialog cannot have the right value for the handle part...
is not clear.

When you ask the question, provide more details and relevant code fragments. Please post here:

1) Full thread creation code
2) Full dialog creation code
3) Thread function
4) Dialog message handler
5) Exact description of the problem - program is freezing (where), or progress bar is not moving, or handle is invalid (what handle, where?) etc.
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

xenia27Author Commented:
1. int MainFun()
{
  DlgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE )ProgressDlg, NULL, 0, &ThreadID);

  if (DlgThread != NULL)
      CloseHandle(DlgThread);

  // here I tried to detect COM Port with CreateFile with for-loops with
  // the combination of baudrate, databits...etc
  // Then I send Message to update progress
  SendMessage(hwndPB, PBM_SETPOS, 100, 0); <-  here the hwndPB, a handle, is incorrect
  EndDialog(hwndDlg, NULL); <- hwndDlg is invalid, too
  // hwndPB and hwndDlg are global vairlabes
  // and they suppose to be sat in "ProgressDlgProc"
 // PBM_SETPOS is defined in "commctrl.h" which is in a library.
}

////////////////////////////////////////////////////////////////////////////////
2. void WINAPI ProgressDlg()
{
      DialogBox(hInst, (LPCSTR)IDD_DetectProgress, gHwnd, ProgressDlgProc); <-- where the program freezed
}

//////////////////////////////////////////////////////////////////////////////

3. BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
          case WM_INITDIALOG:
                        hwndDlg = hDlg;
                        hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                        SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
                        SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);
                  return 0;
      }
      return FALSE;
}

***************************************************************************

Is these better?  Or can I have your email so I can send the codes?  Sorry for your inconvenience.  >"<
0
xenia27Author Commented:
Or if there is any better way to create a progress bar or an easier way???  I'm using VC++ of course...Any suggestions??? ^^"
0
AlexFMCommented:
All this code is completely wrong. Dialog box should be created in the main thread. In the WM_INITDIALOG message handler create worker thread which should scan COM ports and post user-defined message to the dialog. Dialog handles these messages in the main thread and update progress bar.

#define WM_PROGRESSMESSAGE WM_APP + 100

int MainFun()
{
    // create dialog here
    // ProgressDlgProc is dialog function
}


BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
         case WM_INITDIALOG:
                    hwndDlg = hDlg;
                    hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                    SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
                    SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);

                    // create worker thread here passing dialog handler to it as parameter

                    break;
         case WM_PROGRESSMESSAGE:

                    // update progress bar here

                    break;                  

               return 0;
     }
     return FALSE;
}



// in the thread function:
get dlg handler from thread parameter

while ( some loop )
{
    // do something (detect COM port etc.)

    PostMessage(hDlg, WM_PROGRESSMESSAGE, n, 0);  // n is progress step
}
0
xenia27Author Commented:
So your suggestion is that I should do this??

int MainFunc
{
  DialogBox(hInst, (LPCSTR)IDD_DetectProgress, gHwnd, ProgressDlgProc);

  while (loop)
  {
    PostMessage(hDlg, WM_PROGRESSMESSAGE, n, 0);
  }
}

BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
         case WM_INITDIALOG:
                    hwndDlg = hDlg;
                    hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                    SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
                    SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);

                    // create worker thread here passing dialog handler to it as parameter
>>               Question here:
>>               I'm confused about the dialog handler...I thought hwndDlg and hwndPB are the dialog
>>               handlers and they are global variables...
                    break;
         case WM_PROGRESSMESSAGE:

                    // update progress bar here
>>               Question again:
>>               How can you update the progress bar??  Isn't that I can update my progress bar with
>>               "SendMessage"???
                    break;                  

               return 0;
     }
     return FALSE;
}


Thanks for your advise! ^^


Xenia
0
xenia27Author Commented:
Hi,

Is there any example that I can study???  Please help me~~  >"<

Xenia
0
AlexFMCommented:
#define WM_PROGRESSMESSAGE WM_APP + 100   // wParam - progress bar position

int MainFunc
{
  DialogBox(hInst, (LPCSTR)IDD_DetectProgress, gHwnd, ProgressDlgProc);
}

BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
         case WM_INITDIALOG:
                    hwndDlg = hDlg;
                    hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                    SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
                    SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);

                    // start worker thread
                    unsigned threadID;
                   _beginthreadex(NULL,  0, ThreadProc, hDlg, 0, &threadID);

                    break;
         case WM_PROGRESSMESSAGE:

                    // update progress bar here
                    SendMessage(hwndPB, PBM_SETSTEP, wParam, 0);
                    break;                  

     }
     return FALSE;
}

unsigned ThreadProc(LPVOID param)
{
    HWND hDlg = (HWND)param;

    while ( ... )
    {
          // do something

          PostMessage(hDlg, WM_PROGRESSMESSAGE, n, 0);  // n - required progress bar position
    }
}
0
AlexFMCommented:
I will be off-line for number of hours, so I give some explanations to this code which can help you to implement it.

1) _beginthreadex is defined in process.h. If process.h is included and _beginthreadex is not compiled, open Project - Settings - C++ - Code Generation Category and select multi-threading Dll instead of single-threading Dll.

2) 4-th parameter of _beginthreadex may be any value which is passed to thread function as parameter. In this case we pass dialog handler, and thread uses it to post messages back to dialog. Thread function gets dialog handler in LPVOID param and casts it to HWND.

3) WM_PROGRESSMESSAGE is used-defined message which is posted from worker thread to the dialog. It's wParam parameter contains progress bar position. Dialog function updates progress bar using this parameter value.

I hope this information is enough to make the code working. You can ask more if you need.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
xenia27Author Commented:
Hi, AlexFM,

Thanks for yor information...I'll try to work with it today...^^"...If I got more question, I'll definitely ask again~  Thank you~~  ^^



Xenia
0
xenia27Author Commented:
Hi,

I got this problem...error C2065: '_beginthreadex' : undeclared identifier
I did what you said in the previous message...including <process.h> and made some adjustments in the setting part....but it still didn't complie..
0
xenia27Author Commented:
Hi,

I have this question...can I use CreateThread instead of using _beginthreadex???
What's the difference bwteen these two functions?? ^^  Thanks for your help.


Xenia
0
AlexFMCommented:
Jeffrey Richter's "Programming Applications for Microsoft Windows 2000" contains explanation why _beginthreadex is better than CreateThread, I don't remember details. _beginthreadex is deined in PROCESS.H:

#ifdef  _MT
_CRTIMP unsigned long __cdecl _beginthreadex(void *, unsigned,
        unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
#endif

_MT is defined in project settings when we select DEbug Multithreaded (for Debug configuration) or Multithreaded (for Release configuration) run-time library. See MSDN topic:
/MD, /ML, /MT, /LD   (Use Run-Time Library)
0
AlexFMCommented:
_beginthreadex calls CreateThread, but first it makes some other important things (I don't remember what exactly).
0
xenia27Author Commented:
Hi,

I got this question...about my project of course...

I noticed that the handle was wrong because the ProgressDlgProc was called seconds later after SendMessage...so the handle was wrong...So what can I do to adjust it?  I tried to Sleep for a while but it seems it won't work...>"<  And I found some discussion before but I cannot find it now...Please help me...


Xenia
0
AlexFMCommented:
Please describe with more detailes - code, where and what happened.
0
xenia27Author Commented:
Here is what happened in my codes..

int MainFunc
{
  DlgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE )ProgressDlg, NULL, 0, &ThreadID);

  if (DlgThread != NULL)
      CloseHandle(DlgThread);
  Sleep(2000);
  for(conditions...)
  {
    // here I use CreateFile for detecting COM port
    // and then, I use GetPage function to know whether the port is connected or not.
    Sleep(5000);
>>>   SendMessage(hwndPB, PBM_STEPIT, 0, 0); <-- when this function called, ProgressDlgProc is not called yet...so hwndPB has the wrong value...
  }
  EndDialog(hwndDlg, NULL);
>>>  // in the end of this function...ProgressDlgProc called...
}

void WINAPI ProgressDlg()
{
    DialogBox(hInst, (LPCSTR)IDD_DetectProgress, gHwnd, ProgressDlgProc);
}


BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
          case WM_INITDIALOG:
            hwndDlg = hDlg;
            hwndPB = GetDlgItem(hDlg, IDC_DetectProgress);
                      SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
            SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);
            return TRUE;
      }

      return FALSE;
}

/////////////////////////////////////////////////
Ok...this is my old codes...but I think I have to work it out with the old codes...>"<
I tried Sleep in order to delay for SendMessage in the MainFunc after CreateThread...but there is always two seconds difference...and ProgressDlgProc is always late for two seconds..so SendMessage in MainFunc has the wrong handle.
So what can I do for this project?  Thanks for your helps~~~  ^^
0
AlexFMCommented:
Please change your code according to my recommendations. Your code is completely wrong and cannot work in any case. It's impossible to say how to correct it.
COM ports scanning which is made in the main thread prevents main thread message loop to handle window messages. This is only one problem of this code - I don't see a reason to find and describe all problems in it.
Rewrite your code according to my post from 12/12/2003 04:17AM PST, I don't think this is a hard work. After this ask specific questions if there are problems.

0
xenia27Author Commented:
Hi,

I finally get this problem done...but I have another problem....>"<
After detecting the device, I would like to restart the windows...so I use "ExitWindowsEx(EWX_REBOOT, 0);"  BUT...I got this error message right after I execute the command...it's error code: 1314...which means "A required privilege is not held by the client."  So what can I do with this problem??  Help~  Please~~  ^^

Thanks for the helps~~~~



Xenia
PS...is this description clear enough????
0
xenia27Author Commented:
Hi, Hi,

I got my problem solved already~  Finally~  ^^  Thanks for all the helps~~~  




Xenia
0
AlexFMCommented:
Yes, the description is clear :-)
0
xenia27Author Commented:
Hi, ^^

I'm so happy now that my project is done...at least one of the difficult part is done...^^
Now...I'm studying how to create windows service...^^...

Anyway, thanks for your helps.

Xenia
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.