user-0 提问: PostQuitMessage和PostMessage( WM_QUIT ) 有区别吗？

回复:
user: user-1
content: https://bbs.csdn.net/topics/390374955

user: user-0
content: 引用 9 楼 赵4老师 的回复:https://bbs.csdn.net/topics/390374955 意外收获啊，感谢感谢

user: user-0
content: 引用 10 楼 早打大打打核战争 的回复:Windows NT 4的源码在1999年就泄露了，Windows 2000的源码在2001年也泄露了，楼主到现在还不知道~~~ 完全不知道这事。。。 这不是商业机密吗？竟然会泄漏？？

user: user-2
content: Windows NT 4的源码在1999年就泄露了，Windows 2000的源码在2001年也泄露了，楼主到现在还不知道~~~

user: user-1
content: 参考PostQuitMessage源代码

user: user-0
content: 引用 5 楼 赵4老师 的回复:windows_2000_source_code\win2k\private\ntos\w32\ntuser\client\client.c     3381: /**************************************************************************\     3382: * PostQuitMessage     3383: *     3384: * 22-Jul-1991 mikeke    Created     3385: \**************************************************************************/     3386:      3387: VOID PostQuitMessage(     3388:     int nExitCode)     3389: {     3390:     NtUserCallOneParam(nExitCode, SFI__POSTQUITMESSAGE);     3391: }  哇，强，竟然有源码，你是怎么弄到的，可以发我一份吗？ 还有就是，我觉得这几个源码给的有问题，虽然PostQuitMessage的源码给了，但是它调用的NtUserCallOneParam没有；PostMessage没有，在WU32PostMessage里调用了PostMessage应该是更低一层的函数，所以对比WU32PostMessage和只有一行代码的PostQuitMessage，额，感觉没啥用啊

user: user-1
content: d:\windows_2000_source_code\win2k\private\mvdm\wow32\wumsg.c      1509: /*++     1510:     void PostQuitMessage(<nExitCode>)     1511:     int <nExitCode>;     1512:      1513:     The %PostQuitMessage% function informs Windows that the application wishes     1514:     to terminate execution. It is typically used in response to a WM_DESTROY     1515:     message.     1516:      1517:     The %PostQuitMessage% function posts a WM_QUIT message to the application     1518:     and returns immediately; the function merely informs the system that the     1519:     application wants to quit sometime in the future.     1520:      1521:     When the application receives the WM_QUIT message, it should exit the     1522:     message loop in the main function and return control to Windows. The exit     1523:     code returned to Windows must be the <wParam> parameter of the WM_QUIT     1524:     message.     1525:      1526:     <nExitCode>     1527:         Specifies an application exit code. It is used as the wParam parameter     1528:         of the WM_QUIT message.     1529:      1530:     This function does not return a value.     1531: --*/     1532:      1533: ULONG FASTCALL WU32PostQuitMessage(PVDMFRAME pFrame)     1534: {     1535:     register PPOSTQUITMESSAGE16 parg16;     1536:      1537:     GETARGPTR(pFrame, sizeof(POSTQUITMESSAGE16), parg16);     1538:      1539:     PostQuitMessage(INT32(parg16->wExitCode));     1540:      1541:     FREEARGPTR(parg16);     1542:     RETURN(0);     1543: }

user: user-1
content: d:\windows_2000_source_code\win2k\private\mvdm\wow32\wumsg.c:      1338: /*++     1339:     BOOL PostMessage(<hwnd>, <msg>, <wParam>, <lParam>)     1340:     HWND <hwnd>;     1341:     WORD <msg>;     1342:     WORD <wParam>;     1343:     LONG <lParam>;     1344:      1345:     The %PostMessage% function places a message in a window's application queue,     1346:     and then returns without waiting for the corresponding window to process the     1347:     message. Messages in a message queue are retrieved by calls to the     1348:     %GetMessage% or %PeekMessage% function.     1349:      1350:     .*     1351:     .* DA's: the following parameters section should be identical to the     1352:     .*       parameters section in the sdmsg.ref file. If there is a change     1353:     .*       to this section, the identical change should be made in the other     1354:     .*       file.     1355:     .*     1356:      1357:     <hwnd>     1358:         Identifies the window that is to receive the message. If this parameter     1359:         is 0xFFFF (-1), the message is sent to all top-level windows.     1360:      1361:     <msg>     1362:         Specifies the message to be sent.     1363:      1364:     <wParam>     1365:         Specifies additional message information. The contents of this     1366:         parameter depends on the message being sent.     1367:      1368:     <lParam>     1369:         Specifies additional message information. The contents of this     1370:         parameter depends on the message being sent.     1371:      1372:     The return value is TRUE if the message is posted, or FALSE if it is not.     1373:      1374:     An application should never use the %PostMessage% function to send a message     1375:     to a control.     1376:      1377:     .cmt     1378:     27-Oct-1990 [ralphw]     1379:      1380:     The following is a rewording of the previous documentation. However, it     1381:     needs confirmation from development as to its technical accuracy before it     1382:     can be released for public consumption.     1383:      1384:     If the message is being sent to another application, and the <wParam> or     1385:     <lParam> parameters are used to pass a handle or pointer to global memory,     1386:     the memory should be allocated by the %GlobalAlloc% function using the     1387:     GMEM_NOT_BANKED flag. In a system using expanded memory (EMS), this ensures     1388:     that the memory is not in in a different bank of memory from the application     1389:     using the memory.     1390:     .endcmt     1391: --*/     1392:      1393: ULONG FASTCALL WU32PostMessage(PVDMFRAME pFrame)     1394: {     1395:     LONG l;     1396:     UINT f2;     1397:     WPARAM f3;     1398:     LPARAM f4;     1399:     HWND hwnd;     1400:     register PPOSTMESSAGE16 parg16;     1401:     MSGPARAMEX mpex;     1402:     DWORD err = NO_ERROR;     1403:      1404:     GETARGPTR(pFrame, sizeof(POSTMESSAGE16), parg16);     1405:      1406:     // Apps should never use PostMessage to post messages that have     1407:     // pointers to structures, because those messages will show up in     1408:     // GetMessage, and if GetMessage tries to thunk them (ie, tries to     1409:     // call back to the 16-bit kernel to allocate some 16-bit memory to     1410:     // copy the converted 32-bit structure into), we have no way of     1411:     // knowing when to free that 16-bit memory.     1412:     //     1413:     // BUGBUG 22-Aug-91 JeffPar:  a flag should be added to ThunkMsg16     1414:     // indicating whether or not such allocations are permissible;  this     1415:     // flag should be passed on to all the ThunkXXMsg16 subfunctions,     1416:     // and each of those subfunctions should assert the flag is false     1417:     // whenever allocating 16-bit memory.     1418:      1419:      1420:     //     1421:     // Used by 16->32 DDE thunkers.     1422:     //     1423:      1424:     WOW32ASSERT(fWhoCalled == FALSE);     1425:     fWhoCalled = WOWDDE_POSTMESSAGE;     1426:      1427:     f2 = (UINT)WORD32(parg16->f2);     1428:     f3 = (WPARAM)(WORD32(parg16->f3));     1429:     f4 = (LPARAM)(LONG32(parg16->f4));     1430:      1431:     mpex.lReturn = 0;     1432:     mpex.Parm16.WndProc.hwnd   = parg16->f1;     1433:     mpex.Parm16.WndProc.wMsg   = (WORD)f2;     1434:     mpex.Parm16.WndProc.wParam = (WORD)f3;     1435:     mpex.Parm16.WndProc.lParam = f4;     1436:     mpex.iMsgThunkClass = 0;     1437:      1438:     // The Reader.exe shipped with Lotus 123MM version has a message     1439:     // synchronization problem.  Force proper synchronization by     1440:     // converting this PostMessage call to a SendMessage().     1441:     if ((f2 == WM_VSCROLL) &&     1442:          ((f3 == SB_THUMBTRACK) || (f3 == SB_THUMBPOSITION)) &&     1443:          (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SENDPOSTEDMSG) ) {     1444:      1445:         l = (LONG)WU32SendMessage(pFrame);     1446:         FREEARGPTR(parg16);     1447:         RETURN((ULONG) l);     1448:     }     1449:      1450:     hwnd = ThunkMsg16(&mpex);     1451:      1452:     // Note: ThunkMsg16 may have caused 16-bit memory movement     1453:     FREEARGPTR(pFrame);     1454:     FREEARGPTR(parg16);     1455:      1456:     WOW32ASSERT(fWhoCalled == WOWDDE_POSTMESSAGE);     1457:     fWhoCalled = FALSE;     1458:     if (hwnd) {     1459:      1460:         l = PostMessage(hwnd, mpex.uMsg, mpex.uParam, mpex.lParam);     1461:      1462:         if (!l)     1463:             err = GetLastError();     1464:      1465:         mpex.lReturn = l;     1466:         if (MSG16NEEDSTHUNKING(&mpex)) {     1467:             (mpex.lpfnUnThunk16)(&mpex);     1468:         }     1469:      1470:      1471:         // If the post message failed, then the message was probably one     1472:         // that has pointers and therefore can not be posted. (MetaDesign     1473:         // tries to post these kind of messages.) If the destination was a     1474:         // WOW app, then make it into a private message, and try the post     1475:         // again.  We don't have to worry about thunking since both the source     1476:         // and destination are in the WOW address space.     1477:      1478:         if (err == ERROR_INVALID_PARAMETER) {     1479:             PWW   pww;     1480:             DWORD dwpid;     1481:      1482:             pww = FindPWW(hwnd);     1483:      1484:             // was added for WM_DRAWITEM messages which are probably intended     1485:             // for owner drawn std-type classes.  see bug #2047 NTBUG4     1486:             if (pww != NULL && GETICLASS(pww, hwnd) != WOWCLASS_WIN16) {     1487:      1488:                 // make sure we're in the same vdm process     1489:                 if (!(GetWindowThreadProcessId(hwnd, &dwpid) &&     1490:                       (dwpid == GetCurrentProcessId()))) {     1491:                           return 0;     1492:                 }     1493:      1494:                 mpex.lReturn = PostMessage(hwnd, f2 | WOWPRIVATEMSG, f3, f4);     1495:             }     1496:         }     1497:     }     1498:      1499:     FREEARGPTR(parg16);     1500:     RETURN((ULONG)mpex.lReturn);     1501: }

user: user-1
content: windows_2000_source_code\win2k\private\ntos\w32\ntuser\client\client.c     3381: /**************************************************************************\     3382: * PostQuitMessage     3383: *     3384: * 22-Jul-1991 mikeke    Created     3385: \**************************************************************************/     3386:      3387: VOID PostQuitMessage(     3388:     int nExitCode)     3389: {     3390:     NtUserCallOneParam(nExitCode, SFI__POSTQUITMESSAGE);     3391: }

user: user-0
content: 引用 2 楼 轻箬笠 的回复:Remarks The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.  When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message.  好像就发个WM_QUIT吧，发完就立即返回了 文字描述里就这一个差别——“该函数只是向系统指示线程在将来某个时间请求退出”，我想过，真的是因为调用了PostQuitMessage才通知系统线程将要退出的吗？我觉得应该是系统检测了WM_QUIT消息开始准备的，既然消息循环都是检测WM_QUIT消息退出，那干嘛非得在调用PostQuitMessage后准备，完全可以检测WM_QUIT来准备

user: user-0
content: 引用 1 楼 赵4老师 的回复:参考PostQuitMessage源代码 windows API不是闭源的吗？

user: user-3
content: Remarks The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.  When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message.  好像就发个WM_QUIT吧，发完就立即返回了