Solved

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

Posted on 2003-12-11
23
440 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
 

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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Named range not carried over 10 57
fizzArray  challenge 1 47
modThree challenge 4 64
Use of condition with 'serial' in ansible 2 36
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

706 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now