Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 2003-12-11
23
444 Views
Last Modified: 2013-11-20
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

0
Comment
Question by:xenia27
  • 13
  • 9
23 Comments
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9925771
Are you calling any dialog specific functions from thread (instead of posting messages..)...?

If you, change that to PostMessage

Rosh L)
0
 

Author Comment

by:xenia27
ID: 9926031
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9926072
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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

Author Comment

by:xenia27
ID: 9926135
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
 

Author Comment

by:xenia27
ID: 9926167
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9926388
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
 

Author Comment

by:xenia27
ID: 9926418
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
 

Author Comment

by:xenia27
ID: 9926466
Hi,

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

Xenia
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9927719
#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
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 9929673
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
 

Author Comment

by:xenia27
ID: 9939254
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
 

Author Comment

by:xenia27
ID: 9939448
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
 

Author Comment

by:xenia27
ID: 9939457
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9940159
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9940164
_beginthreadex calls CreateThread, but first it makes some other important things (I don't remember what exactly).
0
 

Author Comment

by:xenia27
ID: 9940376
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9940572
Please describe with more detailes - code, where and what happened.
0
 

Author Comment

by:xenia27
ID: 9940608
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9940658
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
 

Author Comment

by:xenia27
ID: 9947372
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
 

Author Comment

by:xenia27
ID: 9947471
Hi, Hi,

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




Xenia
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9947822
Yes, the description is clear :-)
0
 

Author Comment

by:xenia27
ID: 9947832
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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question