Sample program to create multiple threads

I used the CreateThread call and the Heap functions to create a simple sample program that spawns a separate thread that displays a MessageBox

Try running it and you will see a MessageBox. However, unlike a normal MessageBox in your application, this one is on a separate thread, and thus the main thread can continue processing.

The code allocates some memory and writes some bytes of x86 machine code to execute. Those bytes simply put up the MessageBox and return.

The MessageBox strings need to be allocated and freed, and the strings and the code must not be freed until after the thread terminates by Returning.








#define CREATE_SUSPENDED                  0x00000004

#define INFINITE            0xFFFFFFFF 

#define WAIT_TIMEOUT                     258



DECLARE integer LoadLibrary IN WIN32API string

DECLARE integer FreeLibrary IN WIN32API integer

DECLARE integer GetProcAddress IN WIN32API integer hModule, string procname

DECLARE integer CreateThread IN WIN32API integer lpThreadAttributes, ;

      integer dwStackSize, integer lpStartAddress, integer lpParameter, integer dwCreationFlags, integer @ lpThreadId

DECLARE integer ResumeThread IN WIN32API integer thrdHandle

DECLARE integer CloseHandle IN WIN32API integer Handle

DECLARE integer GetProcessHeap IN WIN32API

DECLARE integer HeapAlloc IN WIN32API integer hHeap, integer dwFlags, integer dwBytes

DECLARE integer HeapFree IN WIN32API integer hHeap, integer dwFlags, integer lpMem

DECLARE integer WaitForSingleObject IN WIN32API integer hHandle, integer dwMilliseconds


hModule = LoadLibrary("user32")




hProcHeap = GetProcessHeap()

sCaption="This is a MessageBox running in a separate thread"+CHR(0)     && null terminate string

adrCaption = HeapAlloc(hProcHeap, 0, LEN(sCaption))   && allocate memory for string

SYS(2600,adrCaption,LEN(sCaption),sCaption)     && copy string into allocated mem


* int 3 = cc  (Debug Breakpoint: attach a debugger dynamically)

* nop = 90

* push 0  = 6a 00

* push eax = 50

* push 0x12345678 = 68 78 56 34 12

* ret 4 = c2 04 00

* mov eax, esp    = 8B c4

* mov eax, 0x12345678 = B8 78 56 34 12

* call eax  = ff d0


*sCode = sCode + CHR(0xcc)

sCode = sCode + CHR(0x6a) + CHR(0x00)     && push 0

sCode = sCode + CHR(0x68) + BINTOC(adrCaption,"4rs")  && push the string caption

sCode = sCode + CHR(0x68) + BINTOC(adrCaption,"4rs")  && push the string caption

sCode = sCode + CHR(0x6a) + CHR(0x00)     && push the hWnd

sCode = sCode + CHR(0xb8) + BINTOC(adrMessageBox,"4rs")     && move eax, adrMessageBox

sCode = sCode + CHR(0xff) + CHR(0xd0)     && call eax

sCode = sCode + CHR(0xc2)+CHR(0x04)+CHR(0x00)   && ret 4


AdrCode=HeapAlloc(hProcHeap, 0, LEN(sCode))     && allocate memory for the code


SYS(2600,AdrCode, LEN(sCode), sCode)      && copy the code into the string


dwThreadId =0

?"Starting thread count = ",GetThreadCount()


hThread = CreateThread(0,1024, AdrCode, 0, CREATE_SUSPENDED, @dwThreadId)

?"Thread handle = ",hThread

?"Thread ID = ", dwThreadID

ResumeThread(hThread)   && Start the thread



DO WHILE WaitForSingleObject(hThread, 100) = WAIT_TIMEOUT   && wait 100 msecs for the thread to finish

      ?i,"Current thread count",GetThreadCount()



?"Final thread count = ",GetThreadCount()






HeapFree(hProcHeap, 0, AdrCode)     && if the thread hasn't finished, we're releasing the executing code and it'll crash

HeapFree(hProcHeap, 0, adrCaption)





PROCEDURE GetThreadCount as Integer

      *Use WMI to get process information

      objWMIService = GetObject("winmgmts:\\.\root\cimv2")

      colItems = objWMIService.ExecQuery("Select * from Win32_Process where processid = "+TRANSFORM(_vfp.ProcessId))

      For Each objItem in colItems

            nRetval = objItem.ThreadCount


      RETURN nRetval


Comments (41)
  1. Alan Stevens says:


    This is very cool!  Please expand on this in Sedna, so we can launch multiple threads in VFP.


  2. Great sample, but can we run a foxpro code on the new thread?

    We have to get a pointer (AdrCode) to foxpro procedure/function and pass it to CreateThread()…

    Is there a way to get such pointer?

  3. Good example, if you put this function as part native of VFP (Sedna), this was great feature.

  4. Calvin_Hsia says:

    Alan, Jausz, Franklin: If you could run VFP code on multiple threads, what scenarios will this enable for you? How will you use it?


  5. Rick Strahl says:


    I also posted a few .NET examples that do something similar and I actually think that using .NET in that situation is easier. The other advantage of using .NET in thi scenario is that you could call a Visual FoxPro COM component from the multithreaded code – in fact I showed how to do this in a recent article with a generic COM callable .NET component that can execute another COM component which can be VFP created.

    Multi-threading can come in very handy in a number of situations. Send and forget operation of a lengthy task. In Web applications Aysnc tasks can be used to fire of a long running task and provide feedback so the Web client can see progress information. Offloading blocking user interfaces (while downloading a file for example) is another where I use multi-threading often…

    It would be very cool if there was a way for VFP to create a new thread and then call back into FoxPro code. In fact I seem to remember I played with that a few years ago with the FoxPro library kit, but it wasn’t very happy when the call returned on a new thread <g>.

  6. Rick Strahl says:

    BTW, what’s the reason for calling LoadLibrary on User32? Isn’t that available on the standard Win32API stack already?

  7. Calvin_Hsia says:

    In this sample, LoadLibrary for User32.dll is needed because the return value is passed to GetProcAddress. You’re right that User32.dll is already loaded, so LoadLibrary doesn’t have to *load* the DLL: it just returns the hModule (which is the module address).

    See next blog post for sample that calls VFP code in a thread proc.

  8. Dimitrios Papadopoulos says:


    it would be great if you could run fox code in different threads. Actually my scenarios are more or less as Rick’s. Here are some scenarios which I would use this option for :

    a. I am running a remote – or local – sql query, or queries against several remote databases which at the end the different cursor resultsets must be localy joined. The queries take long because of complexity but the result sets are just a few records …, asynchronous sqlexec does not help in this case.

    b. I have a service that downloads – in a loop – and parses web pages from several different slow web sites. In order to proceed to the next download the program has to wait the previous …

    c. There are issues with timers also that can be improoved by using multithreading. To be able to have different timers in an application that run code at the same time…

  9. Thanks for this article, Calvin.

    Threading is very powerful and as Rick already stated in his comment as well as in his blog articles. Threading in VFP would be very productive in case of long-term processes. We have several customer projects with huge data processing – monthly/quarterly/yearly billing runs – with about 1.5GB data. So, if the customer starts this process the machine is blocked for approx. 2 hours (depending on the number of clients being processed). So, if we could fork those runs on a separate thread, it would be a lot easier for us *not to block* the application and just show an indicator on a dialog or status bar.

    Same for background downloads and other stuff like this.

    So, in my opinion Threading would be a boost for VFP! Today I’m using a .NET based launcher for COM servers like Rick. But a native solution would be more interesting.

    Kind regards, JoKi

  10. When I posted this Sample program to create multiple threads, I knew the inevitable follow-up question…

  11. Franklin Garzón says:

    If, the colleagues have exposed the principal points for which to implement the MH in VFP as a native part, another case is that nowadays on having executed a process of connection to a WS the machine freezes waiting for the process of response.

  12. Craig Larson says:

    I’m wondering if the majority of users just need a box message to pop up informing them that some process is happening and will be available shortly, would this not be a simpler solution?

    ** C++ code below **

    #include "pro_ext.h"

    #include <string.h>

    char FAR mmsg[254];

    DWORD WINAPI FAR Message(LPVOID aVoidPointer)


    MessageBox(NULL, mmsg, "Separate Thread Support",NULL);

    return (0);


    void FAR mbox(ParamBlk FAR *parm) // the function definition


    DWORD ThreadId;

    char FAR *msg;

    msg = ((char FAR *) _HandToPtr(parm->p[0].val.ev_handle));

    strncpy(mmsg, msg, strlen(msg));

    CreateThread(NULL,0, Message, 0, 0, &ThreadId);  //show messagebox in separate thread

    _RetLogical(1); //return .T.


    FoxInfo myFoxInfo[] ={

    {"MBOX", (FPFI) mbox, 1, "C"},


    extern "C" FoxTable _FoxTable = {

    (FoxTable FAR *)0, sizeof(myFoxInfo)/ sizeof(FoxInfo), myFoxInfo


    ** Fox Code Below **


    _result = .F.

    _result = mbox("Messagebox in separate thread")

    FOR _cnt = 1 TO 5

    WAIT WINDOW "Count = " + STR(_cnt) TIMEOUT 1


    IF (_result)

    WAIT WINDOW "MessageBox Was Displayed" nowait


  13. Olaf Doschke says:

    This is nice in showing, that MT is even possible with some API calls. But the last time I poked some assembler into memory was with the commodore vc 20, not even c64, even with that oldie one could use an assembler :^).

    How would we use MT within VFP?

    1. using API calls with a callback function like MoveFileWithProgress().

    2. nonblocking wait for external processes: Multiple file download, mail sending, COM port polling, whatever.

    Especially in case of the failure of an external process, with a separate thread a timeout is much easier, and that thread may die without affecting the main thread.

    3. putting lengthy porcesses in the background, like backup of large amounts of files, lenghty complex queries (datamining).

    4. seperating tasks into smaller portions being able to run parallel in principle.

    For example with shared memory access, one thread may fill a buffer by reading in a file, one thread may process it (eg compress blocks), the next thread writes the processed data back to disk.

    All this may be done step by step in a single thread, but seperating these three tasks could make use of multiple cpu cores and balance cpu needs.

    5.,6.,7.,8.,9.,… what I even did not think about now.

    Bye, Olaf.

  14. Martin Bauer says:

    I need threading in VFP !

  15. DOUGBAKER says:

    Well, I recently upgraded my workstation to a fast processor with hyper threading. When I run some processes, one virtual processor is maxed, the other one is not doing much. If I could create multiple threads, my hunch is the processor would use hyper threading to run both threads. If I can design the threads to not be dependent on each other,  would  I get faster throughput?

  16. Calvin_Hsia says:

    DougBaker: yes: with hyperthreading or with multiprocessors, throughput can be much improved when there is little interthread resource contention

  17. meimeib says:

    hi,Calvin_Hsia ^_^

    can you demo this code with vfp’s form instead of messageboxA?

    thank you

  18. jimsun says:


    can you tell me how to run a EXE in a thread!

  19. noel says:

    can you give me an easy sample of database programs with problems and foxpro with problems i ned it for my project………. just send to this e-mail thanks im hoping for your rply as soon as posible thank you…..

  20. yothinin says:

    Hi, Calvin

    I need to run VFP’s form look like !!meimeib!!. Can you tell me more.

    Thanks advance

  21. I received a question: Simply, is there a way of interrupting a vfp sql query once it has started short

  22. raja says:

    Need Salesmanwise Report program foxpro 2.6 dos mode, please send sample program my email address.

  23. !saubbesia! says:

    Do you like   ?

    May be you prefer  ?

    Specializes in quality  ?

    Don’t beat me!

  24. 出会い says:


  25. 小向美奈子 says:


  26. 話題の小向美奈子ストリップを隠し撮り!入念なボディチェックをすり抜けて超小型カメラで撮影した神動画がアップ中!期間限定配信の衝撃的映像を見逃すな

  27. 話題の小向美奈子ストリップを隠し撮り!入念なボディチェックをすり抜けて超小型カメラで撮影した神動画がアップ中!期間限定配信の衝撃的映像を見逃すな

  28. セフレ says:


  29. カワイイ子ほど家出してみたくなるようです。家出掲示板でそのような子と出会ってみませんか?彼女たちは夕食をおごってあげるだけでお礼にHなご奉仕をしてくれちゃったりします

  30. 右脳左脳 says:


  31. セレブラブでは性欲のある男性を募集しています。セフレパートナーを探している20代・30代の女性たちが多数登録されています。セレブと遊びたい、Hがしたいという方は無料登録からどうぞ

  32. 逆援助 says:

    セレブ達は一般の人達とは接する機会もなく、その出会う唯一の場所が「逆援助倶楽部」です。 男性はお金、女性はSEXを要求する場合が多いようです。これは女性に圧倒的な財力があるから成り立つことの出来る関係ではないでしょうか?

  33. 救援部 says:


  34. 出会い says:

    まったぁ〜りしたデートがしたいです☆結構いつでもヒマしてます♪ 年齢と名前くらいは入れてくれるとメール返信しやすいかも…

  35. filmmy says:

    Нашел сайт в сети, где Вы сможете найти множество интересных материалов. Здесь можна посмотреть кино разных жанров в режиме онлайн, а можна и скачать фильмы, причем совершенно бесплатно.

    Для любителей легкой эротики есть два раздела: эротика онлайн и скачать эротику,

    <a href="">Фильмы онлайн, скачать фильмы</a>.

  36. Iterbintuit says:

    Текст (слова) песни

    Ты проснешься на рассвете мы с тобою вместе встретим день рождения зари

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Ты не можешь не заметить соловьи живут на свете и простые сизари

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Ты взглянула и минуты остановлены как будто как росинки их бери

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Как прекрасен этот мир посмотри как прекрасен этот мир

    Как прекрасен этот мир посмотри как прекрасен этот мир

  37. logginnoff says:


    Помогите плиз, комп не включается, синий экран и всё 🙁

    Компьютерная помощь приезжали, винды переустановили – непомогает

    сейчас снова синий экран :((

    Комп не трогал, все так и было…

    Или хотя бы куда обратится в Москве? Чтобы недорого..

    Спасибо заранее!

  38. Rafael Ghelardi says:

    Dear Calvin, I'm really courious about the sCode that you have been created. I want to know what is it? Because I never seen nothing like this before. Well, my question is: How can I do this assembly to pass it to a windows api?? What CHR() CODE i have to use?? Please, I Wait for your response.

Comments are closed.

Skip to main content