怎样取得CreateThread创建线程的函数的反回值

sxqvb 2017-12-02 11:56:35
比如:
Dim hThread As Long, hThreadID As Long, Tcm As Long
MciCommand = "play C:\WINDOWS\Media\chimes.wav"
Lb = LoadLibrary("winmm.dll") '载入模块
ProcAdd = GetProcAddress(Lb, "mciExecute") '取得函数入口
hThread = CreateThread(ByVal 0&, ByVal 0&, ProcAdd, ByVal MciCommand, ByVal 0&, hThreadID) '创建线程

mciExecute这个函数会返回一个long的值,要怎样才可以取得
...全文
5710 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
舉杯邀明月 2017-12-23
  • 打赏
  • 举报
回复
直接传给“线程”的参数,只能是1个,这是“约定”、是别人定好的“游戏规则”,   如果你“要走这条路”,那就是无法改变的事实! 但是,它不会去管你这“1个参数”具体的是什么含义。  也许这刚好是我需要传递的一个数据值;  也有可能什么都不是,只是因为“要填补空缺”而已,这个“参数”我根本就不需要…… 以“Win32环境”来说(就比如VB6吧,其它开发环境也可以参考),那个“线程参数”是个“32位数”, 但需要传递“2个、或更多个参数”,是不能直接通过CreateThread( )传递的。 不过,其实“多个参数”,可以事先处理、放到一个“1维数组”中,而这个“线程参数”则是传递它的“数据首址”; 在“线程函数”中,按“约定顺序”和数据首址值,依次取出数据就行了。 当然这种情况需要“自己包装”一下,以便于正确接收及还原传入的参数,  肯定不能象你上面12楼那样,直接用到系统的(或其它第三方DLL的)API函数上。 用这种方式“包装”,别说三个参数,就是300个也没问题。并且可以是不同类型的参数混合的……
sxqvb 2017-12-23
  • 打赏
  • 举报
回复
既然你这么励害,那你给我说说我想传多个叁数要怎么作呢
舉杯邀明月 2017-12-22
  • 打赏
  • 举报
回复
我在上面已经说的很直接了。 都到这步程度了,竟然还说“不知道这是不是IsWindow这个函数的返回值”…… 楼主,我建议你以后到CSDN,逛这个版块吧: http://bbs.csdn.net/forums/FreeZone 编程技术的版块不适合你。
sxqvb 2017-12-21
  • 打赏
  • 举报
回复

    Dim x As Long
    x = Me.hwnd

    Lb = LoadLibrary("user32.dll")              '载入模块
    ProcAdd = GetProcAddress(Lb, "IsWindow")    '取得函数入口(判断是不是窗口)

    hThread = CreateThread(ByVal 0&, ByVal 0&, ByVal ProcAdd, ByVal x, ByVal 0&, hThreadID)     '创建线程
  
    WaitObj = WaitForSingleObject(hThread, INFINITE)    '等待线程结束

    Dim Tcm As Long
    GetExitCodeThread hThread, Tcm  '取线程的反回值
    Debug.Print Tcm
 
    FreeLibrary Lb

上面这个代码,只调用有一个参数和一个反回值的API, 如查x是一个有效的窗口句柄,会打印出来1,如果不是有效的窗口句柄会打印出来0,不知道这是不是IsWindow这个函数的返回值。
赵4老师 2017-12-18
  • 打赏
  • 举报
回复
《Windows核心编程》 《深入解析Windows操作系统-Windows Internals》
舉杯邀明月 2017-12-18
  • 打赏
  • 举报
回复
已经把你“指引到门口”了,还不能明白,我也只能呵呵了…………
PctGL 2017-12-18
  • 打赏
  • 举报
回复
说实话。。。 我觉得这种调用方式有点bt。。。 单开一个线程只为调用一个api,是为了异步吗? 而且常规方法肯定是不可能得到你想要的内容的
greatbody 2017-12-17
  • 打赏
  • 举报
回复
楼主问的是,创建一个线程,调用线程中的函数,希望获取函数的返回值。
舉杯邀明月 2017-12-13
  • 打赏
  • 举报
回复
引用 6 楼 sxqvb 的回复:
出差才回来 Private Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long 这是CreateThread 定义,和你说的一样 GetExitCodeThread这个不是取线程状态的函数吗 我想问的是: GetExitCodeThread 创建了一个线程,这个线程调用了 mciExecute 这个API,现在需要得到 mciExecute 这个的返回值
看清楚:GetExitCodeThread → Get Exit Code Threaed 简单的“望文生义”,也知道不是“取线程状态”啊………… 自己看看“百度百科”中的介绍啊,那是中文的,你不会说“不认识汉字”吧。
sxqvb 2017-12-13
  • 打赏
  • 举报
回复
出差才回来 Private Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long 这是CreateThread 定义,和你说的一样 GetExitCodeThread这个不是取线程状态的函数吗 我想问的是: GetExitCodeThread 创建了一个线程,这个线程调用了 mciExecute 这个API,现在需要得到 mciExecute 这个的返回值
赵4老师 2017-12-05
  • 打赏
  • 举报
回复
CreateThread The CreateThread function creates a thread to execute within the address space of the calling process. HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes DWORD dwStackSize, // initial thread stack size LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function LPVOID lpParameter, // argument for new thread DWORD dwCreationFlags, // creation flags LPDWORD lpThreadId // pointer to receive thread ID ); Parameters lpThreadAttributes Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited. Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor. dwStackSize Specifies the initial commit size of the stack, in bytes. The system rounds this value to the nearest page. If this value is zero, or is smaller than the default commit size, the default is to use the same size as the calling thread. For more information, see Thread Stack Size. lpStartAddress Pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread. For more information on the thread function, see ThreadProc. lpParameter Specifies a single 32-bit parameter value passed to the thread. dwCreationFlags Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state, and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation. At this time, no other values are supported. lpThreadId Pointer to a 32-bit variable that receives the thread identifier. Windows NT: If this parameter is NULL, the thread identifier is not returned. Windows 95 and Windows 98: This parameter may not be NULL. Return Values If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL. To get extended error information, call GetLastError. Windows 95 and Windows 98: CreateThread succeeds only when it is called in the context of a 32-bit program. A 32-bit DLL cannot create an additional thread when that DLL is being called by a 16-bit program. Remarks The new thread handle is created with THREAD_ALL_ACCESS to the new thread. If a security descriptor is not provided, the handle can be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread. The thread execution begins at the function specified by the lpStartAddress parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value. The CreateThread function may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs). The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread. When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting on the object. The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle. The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means that the following restrictions hold: During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process. Only one thread in a process can be in a DLL initialization or detach routine at a time. ExitProcess does not return until no threads are in their DLL initialization or detach routines. A thread that uses functions from the C run-time libraries should use the beginthread and endthread C run-time functions for thread management rather than CreateThread and ExitThread. Failure to do so results in small memory leaks when ExitThread is called. Windows CE: The lpThreadAttributes parameter must be set to NULL. The dwStackSize parameter must be zero. Only zero or CREATE_SUSPENDED values are supported for the dwCreationFlags parameter. QuickInfo Windows NT: Requires version 3.1 or later. Windows: Requires Windows 95 or later. Windows CE: Requires version 1.01 or later. Header: Declared in winbase.h. Import Library: Use kernel32.lib. See Also Processes and Threads Overview, Process and Thread Functions, CloseHandle, CreateProcess, CreateRemoteThread, ExitProcess, ExitThread, GetExitCodeThread, GetThreadPriority, ResumeThread, SetThreadPriority, SECURITY_ATTRIBUTES, ThreadProc
舉杯邀明月 2017-12-04
  • 打赏
  • 举报
回复
CreateThread( ) 的“第三个参数”,是“输入参数”,不是用来“返回数据”的! 注意:VB6的“API浏览器”带的声明信息 Win32API.txt ,它的第3个参数形式声明是错误的(某些“修改版”同样的错误)!   VB6中应该加上 ByVal 才对!在Win32API.txt中是没有指定“传递方式”的,那就是默认的ByRef传递。 若不更正,如果要“正确传递”,那么就要在调用CreateThread( ) 语句的第3个参数前加ByVal,   否则传入的不是“函数地址”,而是传入的“变量地址”或“临时变量的地址”了。 可以查阅MSDN,仔细“理解”那个参数的作用,可以看到它是“输入”用的、是“函数入口首址”。 你要得到那个“函数返回值”,就是需要通过我在楼上说的那个API函数 ! 在线程创建成功、并且线程函数被正常执行完成后,这个“函数”就有一个“返回值”,   而这个值就需要用 GetExitCodeThread( ) 才能获取!
sxqvb 2017-12-03
  • 打赏
  • 举报
回复
不是的,我不是要CreateThread这个的返回值,我是想要CreateThread调用的函数的返回值,也是就CreateThread的第三个参数对应的函数的返回值。
舉杯邀明月 2017-12-03
  • 打赏
  • 举报
回复
Function GetExitCodeThread Lib "Kernel32" (ByVal hThread As Long, ByRef ExitCode As Long) As Long 如果API调用执行成功,ExitCode的返回值是 STILL_ACTIVE 表示线程还没有结束(还在执行中)。
舉杯邀明月 2017-12-03
  • 打赏
  • 举报
回复
API函数: GetExitCodeThread( ) 楼主查一下相差信息吧。
仿多线程的效果一般有2种办法:第一种是通过定时器;第二种是启动多线程,不同模式下启动函数不同,mfc与API与WIN32下面注意点也是有区别的! VC启动一个新线程的三种方法,有需要的朋友可以参考下。 第一种AfxBeginThread() 用AfxBeginThread()函数创建一个新线程来执行任务,工作者线程的AfxBeginThread的原型如下: CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,   LPVOID lParam,   int nPriority = THREAD_PRIORITY_NORMAL,   UINT nStackSize = 0,   DWORD dwCreateFlags = 0,   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL   );//用于创建工作者线程回值: 成功时返回一个指向新线程线程对象的指针,否则NULL。 pfnThreadProc : 线程的入口函数,声明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能设置为NULL; pParam : 传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程. nPriority : 线程的优先级,一般设置为 0 .让它和主线程具有共同的优先级. nStackSize : 指定新创建线程的栈的大小.如果为 0,新创建线程具有和主线程一样的大小的栈 dwCreateFlags : 指定创建线程以后,线程有怎么样的标志.可以指定两个值: CREATE_SUSPENDED : 线程创建以后,会处于挂起状态,直到调用:ResumeThread 0 : 创建线程后就开始运行. lpSecurityAttrs : 指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性.如果为 NULL, 那么新创建线程就具有和主线程一样的安全性. 如果要在线程内结束线程,可以在线程内调用 AfxEndThread. 一般直接用AfxBeginThread(ThreadProc,this); 示例: UINT myproc(LPVOID lParam){CITTDlg *pWnd = (CITTDlg *)lParam; //将窗口指针赋给无类型指针pWnd->KMeansSegment(); //要执行的函数return 1;}void CITTDlg::KMeansSegment(){// 主要处理函数在这里写}void CITTDlg::OnKMeansSegment() //按钮点击执行{AfxBeginThread(myproc, (LPVOID)this);//启动新的线程} 注意,工作者线程函数必须是全局函数或静态成员函数,不能是普通的成员函数。 第二种CreateThread()函数原型为:HANDLECreateThread( NULL, // 没有安全描述符 0, // 默认线程栈的大小 MyThreadProc, // 线程函数指针,即函数名 (LPVOID)&n, // 传递参数 NULL, // 没有附加属性 NULL // 不需要获得线程号码 ); CreatThread,它返回的是一个句柄;如果不需要再监视线程,则用CloseHandle()关闭线程句柄。 线程函数必须定义为: DWORD WINAPI MyThreadProc(LPVOID pParameter); 下面演示多线程操作控件,点击一个Button然后运行一个线程,将字符串显示在CEdit控件里面; 示例: .h头文件struct hS {CString Tmp;CTestDlg *hWnd; };//定义全局结构体,用来传递自定义消息DWORD WINAPI ThreadProc(LPVOIDlpParam);//线程函数声明,全局函数public: CString chtmp; struct hS *hTmp;protected: HANDLE m_hThread;//线程句柄 CEdit m_Edit;.cpp实现文件//线程执行函数DWORD WINAPI ThreadProc(LPVOID lpParam){//在这里写处理函数struct hS *Tmp2;Tmp2 = (hS*)lpParam;// 操作: Tmp2->hWnd->m_Edit.SetWindowText( (LPTSTR)Tmp2->Tmp );}void CTestDlg::OnBnClickedButton1(){ hTmp->Tmp = chtmp; hTmp->hWnd = this;//关键是把this指针传进去 m_hThread =CreateThread(NULL,0,ThreadProc,hTmp,0,NULL);//创建线程 CloseHandle(m_hThread );} 用CreateThread()函数创建线程将返回一个线程句柄,通过该句柄你可以控制和操作该线程,当你不用时可以一创建线程后就关闭该句柄,有专门的函CloseHandle()。关闭句柄不代表关闭线程,只是你不能在外部控制该线程(比如,提前结束,更改优先级等)。在线程结束后,系统将自动清理线程资源,但并不自动关闭该句柄,所以线程结束后要记得关闭该句柄。 第三种_beginthread() 函数原型为:intptr_t _beginthread( void( *start_address )( void * ), //指向新线程调用的函数的起始地址 unsigned stack_size, //堆栈大小,设置0为系统默认值 void *arglist //传递给线程函数的参数,没有则为NULL ); 返回值: 假如成功,函数将会返回一个新线程的句柄,用户可以像这样声明一个句柄变量存储返回值:   HANDLE hStdOut = _beginthread( CheckKey, 0, NULL )。如果失败_beginthread将返回-1。所在库文件: #include 线程函数的定义: 对于_beginthread()创建线程,其线程函数定义为: void ThreadPro(void * pArguments ); _beginthreadex()为_beginthread()的升级版。 总结:AfxBeginThread是MFC的全局函数,是对CreateThread的封装。 CreateThread是Win32 API函数,AfxBeginThread最终要调到CreateThread。而_beginthread是C的运行库函数
实验目的 (1)掌握Windows系统提供的线程创建与撤销系统调用 (2)掌握Windows系统环境下线程创建与撤销方法 2 实验准备知识 (1)线程创建 CreateThread()完成线程创建。它在调用进程的地址空间上创建一个线程,执行指定的函数,并返回新建立线程的句柄。 原型: HANDLE CreateThread(   LPSECURITY_ATTRIBUTES lpThreadAttributes,   DWORD dwStackSize,   LPTHREAD_START_ROUTINE lpStartAddress,   LPVOID lpParameter,   DWORD dwCreationFlags,   LPDWORD lpThreadId);   参数说明:   lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL,表示使用缺省值。   dwStackSize,线程堆栈大小,一般=0,在任何情况下,Windows根据需要动态延长堆栈的大小。   lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:   DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正确将无法调用成功。   lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。   dwCreationFlags :线程标志,可取值如下   CREATE_SUSPENDED: 创建一个挂起的线程   0 :创建后立即激活。   lpThreadId:保存新线程的id。   返回值:   函数成功,返回线程句柄;函数失败返回false。 (2)撤销线程 ExitThread()用于撤销当前线程 原型: VOID ExitThread( DWORD dwExitCode ); 参数说明: DwExitCode:指定线程返回码 返回值: 该函数没有返回值 用法举例: ExitThread(0); (3)挂起线程 Sleep()用于挂起当前正在执行的线程 原型: VOID Sleep( DWORD dwMilliseconds ); 参数说明: dwMilliseconds:指定挂起时间,单位为ms(毫秒)。 返回值: 该函数没有返回值。 (4)关闭句柄 函数CloseHandle()用于关闭已打开对象的句柄,其作用与释放动态申请的内存空间类似,这样可以释放系统资源,使进程安全运行。 原型: BOOL CloseHandle( HANDLE hObject ); 参数说明: hObject:已打开对象的句柄。 返回值: 成功,返回值为非0值;失败,则返回值为0.
1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联三个进度条类型的变量;并在对话框的初始化函数中,设定进度条的范围;为编辑框关联一个整型的变量;为12个按钮添加消息处理函数; 2. 定义结构体:用做线程函数的参数传递 typedef struct Threadinfo{ CProgressCtrl *progress;//进度条对象 int speed; //进度条速度 int pos; //进度条位置 } thread,*lpthread; 3. 为对话框增加三个句柄,用于标识各个线程; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1.progress=&m_progress1;//进度条对象 thread1.speed=100;//速度 thread1.pos=0;//初始位置 hThread1=CreateThread(NULL,0,ThreadFun,&thread1;,0,0);//创建并开始线程 if (!hThread1) { MessageBox("创建线程失败"); } 7. 编写线程函数(一般是一个死循环,或者需要花费时间很长的算法!否者就失去了多线程的意义) DWORD WINAPI ThreadFun(LPVOID pthread) //线程入口函数 { lpthread temp=(lpthread)pthread;//参数强制转换为结构体类型 temp->progress->SetPos(temp->pos); //设置被传递过来的进度条的位置 while(temp->posspeed); /设置速度 temp->pos++; //增加进度 temp->progress->SetPos(temp->pos); //设置进度条的新位置 GlobalVar--; if(temp->pos==20) { temp->pos=0; //进度条满则归0 } } return true; } 8. 在挂起按钮函数中,编写如下代码: if(SuspendThread(hThread1)==0xFFFFFFFF) { MessageBox("挂起失败!进程可能已经死亡或未创建!"); return; } 9. 在执行按钮函数中,编写如下代码: if(ResumeThread(hThread1)==0xFFFFFFFF) { MessageBox("执行失败!进程可能已经死亡或未创建!"); return; } 10. 在停止按钮函数中,编写如下代码: if(TerminateThread(hThread1,0))//前些终止线程 { CloseHandle(hThread1);//销毁线程句柄 } else { MessageBox("终止进程失败!"); } 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧