Parallel Task (Threads) in VBa, is it possible?

N

NooK

I have a little program in which I would like to run a progress ba
while the program is running so I was wondering if it is possible t
have a thread (Parallel task) running (Increasing the progress bar
while the macro is running?

If so how can I do it?

Best Regards

Noo
 
A

ALEX

Possible but very tough. See:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/htm
l/vbconCreatingMultithreadedTestApplication.asp

People normally do it in C/C++. Here is a sample from MS:
also see

* Bounce - Creates a new thread each time the letter 'a' is typed.
* Each thread bounces a happy face of a different color around the screen.
* All threads are terminated when the letter 'Q' is entered.
*
* This program requires the multithread library. For example, compile
* with the following command line:
* CL /MT BOUNCE.C
*/

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>

#define MAX_THREADS 32

/* getrandom returns a random number between min and max, which must be in
* integer range.
*/
#define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) +
(min))

void main( void ); /* Thread 1: main */
void KbdFunc( void ); /* Keyboard input, thread dispatch */
void BounceProc( char * MyID ); /* Threads 2 to n: display */
void ClearScreen( void ); /* Screen clear */
void ShutDown( void ); /* Program shutdown */
void WriteTitle( int ThreadNum ); /* Display title bar information */

HANDLE hConsoleOut; /* Handle to the console */
HANDLE hRunMutex; /* "Keep Running" mutex */
HANDLE hScreenMutex; /* "Screen update" mutex */
int ThreadNr; /* Number of threads started */
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; /* Console information */


void main() /* Thread One */
{
/* Get display screen information & clear the screen.*/
hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );
ClearScreen();
WriteTitle( 0 );
/* Create the mutexes and reset thread count. */
hScreenMutex = CreateMutex( NULL, FALSE, NULL ); /* Cleared */
hRunMutex = CreateMutex( NULL, TRUE, NULL ); /* Set */
ThreadNr = 0;

/* Start waiting for keyboard input to dispatch threads or exit. */
KbdFunc();

/* All threads done. Clean up handles. */
CloseHandle( hScreenMutex );
CloseHandle( hRunMutex );
CloseHandle( hConsoleOut );
}

void ShutDown( void ) /* Shut down threads */
{
while ( ThreadNr > 0 )
{
/* Tell thread to die and record its death. */
ReleaseMutex( hRunMutex );
ThreadNr--;
}
/* Clean up display when done */
WaitForSingleObject( hScreenMutex, INFINITE );
ClearScreen();
}

void KbdFunc( void ) /* Dispatch and count threads. */
{
int KeyInfo;

do
{
KeyInfo = _getch();
if( tolower( KeyInfo ) == 'a' && ThreadNr < MAX_THREADS )
{
ThreadNr++;
_beginthread( BounceProc, 0, &ThreadNr );
WriteTitle( ThreadNr );
}
} while( tolower( KeyInfo ) != 'q' );

ShutDown();
}

void BounceProc( char *MyID )
{
char MyCell, OldCell;
WORD MyAttrib, OldAttrib;
char BlankCell = 0x20;
COORD Coords, Delta;
COORD Old = {0,0};
DWORD Dummy;

/* Generate update increments and initial display coordinates. */
srand( (unsigned) *MyID * 3 );
Coords.X = getrandom( 0, csbiInfo.dwSize.X - 1 );
Coords.Y = getrandom( 0, csbiInfo.dwSize.Y - 1 );
Delta.X = getrandom( -3, 3 );
Delta.Y = getrandom( -3, 3 );

/* Set up "happy face" & generate color attribute from thread number.*/
if( *MyID > 16)
MyCell = 0x01; /* outline face */
else
MyCell = 0x02; /* solid face */
MyAttrib = *MyID & 0x0F; /* force black background */

do
{
/* Wait for display to be available, then lock it. */
WaitForSingleObject( hScreenMutex, INFINITE );

/* If we still occupy the old screen position, blank it out. */
ReadConsoleOutputCharacter( hConsoleOut, &OldCell, 1, Old, &Dummy );
ReadConsoleOutputAttribute( hConsoleOut, &OldAttrib, 1, Old,
&Dummy );
if (( OldCell == MyCell ) && (OldAttrib == MyAttrib))
WriteConsoleOutputCharacter( hConsoleOut, &BlankCell, 1, Old,
&Dummy );

/* Draw new face, then clear screen lock */
WriteConsoleOutputCharacter( hConsoleOut, &MyCell, 1, Coords,
&Dummy );
WriteConsoleOutputAttribute( hConsoleOut, &MyAttrib, 1, Coords,
&Dummy );
ReleaseMutex( hScreenMutex );

/* Increment the coordinates for next placement of the block. */
Old.X = Coords.X;
Old.Y = Coords.Y;
Coords.X += Delta.X;
Coords.Y += Delta.Y;

/* If we are about to go off the screen, reverse direction */
if( Coords.X < 0 || Coords.X >= csbiInfo.dwSize.X )
{
Delta.X = -Delta.X;
Beep( 400, 50 );
}
if( Coords.Y < 0 || Coords.Y > csbiInfo.dwSize.Y )
{
Delta.Y = -Delta.Y;
Beep( 600, 50 );
}
}
/* Repeat while RunMutex is still taken. */
while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );

}

void WriteTitle( int ThreadNum )
{
char NThreadMsg[80];

sprintf( NThreadMsg, "Threads running: %02d. Press 'A' to start a
thread,'Q' to quit.", ThreadNum );
SetConsoleTitle( NThreadMsg );
}

void ClearScreen( void )
{
DWORD dummy;
COORD Home = { 0, 0 };
FillConsoleOutputCharacter( hConsoleOut, ' ', csbiInfo.dwSize.X *
csbiInfo.dwSize.Y, Home, &dummy );
}
 
N

NooK

Thanks but the link above doesn't exist on MS homepage. Do you have th
correct link?

Looks a bit complicated but possible.

*EDIT* Nevermind, I didn't the continuation of the link on the botto
line

Best Regards

Noo
 
N

NooK

Nice ProgressBar Robin, I am gonna use instead of mine although m
problem still remains being able to run it in parallel with th
program.

What I am doing is splitting the progress demo into 3 functions one t
initialize it, one to increase and another to kill it so I can call th
increase function in the middle of the program but since I run th
shell command for a third party software to do some stuff and there i
no telling how long the program will run I have to halt the progressba
while the second program is being runned there I wanna be able to ru
the progressbar on a second thread.

Anyway if not possible, my solution so far works quite OK.

Best Regards

Noo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top