⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 20. 多任务和多线程.txt

📁 本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序写作的方法
💻 TXT
📖 第 1 页 / 共 5 页
字号:
        
           HDC                                hdc ;
        
           int                                  iTemp ;
        
           TCHAR                                szBuffer[16] ;
        
   
        
           switch (message)
        
           {
        
           case WM_SIZE:
        
                          cyClient = HIWORD (lParam) ;
        
                          return 0 ;
        
        
        
           case   WM_TIMER:
        
                          if (iNum < 0)
        
                          {
        
                                         iNum  = 0 ;
        
                                         iNext = 1 ;
        
                          }
        
        
        
                          iLine = CheckBottom (hwnd, cyClient, iLine) ;
        
                          hdc = GetDC (hwnd) ;
        

                          TextOut (     hdc, 0, iLine * cyChar, szBuffer,
        
                                                               wsprintf (szBuffer, "%d", iNum)) ;
        
                          ReleaseDC (hwnd, hdc) ;
        
                          iTemp         =      iNum ;
        
                          iNum          =      iNext ;
        
                         iNex          +=     iTemp ;
        
                          iLine++ ;
        
                          return 0 ;
        
           }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        

// --------------------------------------------------------------------------
        
// Window 4: Display circles of random radii
        
// ---------------------------------------------------------------------------
        

LRESULT APIENTRY WndProc4 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        
{
        
           static int            cxClient, cyClient ;
        
           HDC                                  hdc ;
        
           int                                  iDiameter ;
        
  
        
           switch (message)
        
           {
        
           case   WM_SIZE:
        
                          cxClient = LOWORD (lParam) ;
        
                          cyClient = HIWORD (lParam) ;
        
                          return 0 ;
        
        
        
           case   WM_TIMER:
        
                          InvalidateRect (hwnd, NULL, TRUE) ;
        
                        UpdateWindow (hwnd) ;
        
        
        
                          iDiameter = rand() % (max (1, min (cxClient, cyClient))) ;
        
                          hdc = GetDC (hwnd) ;
        
        
        
                          Ellipse (hdc,         (cxClient - iDiameter) / 2,
        
                                         (cyClient - iDiameter) / 2,
        
                                         (cxClient + iDiameter) / 2,
        
                                         (cyClient + iDiameter) / 2) ;
        
        
        
                          ReleaseDC (hwnd, hdc) ;
        
                          return 0 ;
        
           }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
// --------------------------------------------------------------------------
        
// Main window to create child windows
        
// --------------------------------------------------------------------------
        

LRESULT APIENTRY WndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        
{
        
           static HWND           hwndChild[4] ;
        
          static TCHAR * szChildClass[] =      { TEXT ("Child1"), TEXT ("Child2"),
        
       TEXT ("Child3"), TEXT ("Child4") } ;
        
           static WNDPROC        ChildProc[] = { WndProc1, WndProc2, WndProc3, WndProc4 } ;
        
           HINSTANCE                     hInstance ;
        
           int                                         i, cxClient, cyClient ;
        
           WNDCLASS                             wndclass ;
        
   
        
           switch (message)
        
           {
        
           case   WM_CREATE:
        
                         hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
        
        
        
                          wndclass.style                                       = CS_HREDRAW | CS_VREDRAW ;
        
                         wndclass.cbClsExtra                  = 0 ;
        
                          wndclass.cbWndExtra                  = 0 ;
        
                          wndclass.hInstance                   = hInstance ;
        
                          wndclass.hIcon                       = NULL ;
        
                          wndclass.hCursor                     = LoadCursor (NULL, IDC_ARROW) ;
        
                         wndclass.hbrBackground        = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        
                          wndclass.lpszMenuName         = NULL ;
        
        
        
                          for (i = 0 ; i < 4 ; i++)
        
                          {
        
                                                 wndclass.lpfnWndProc   = ChildProc[i] ;
        
                                                 wndclass.lpszClassName = szChildClass[i] ;
        
             
        
                                                RegisterClass (&wndclass) ;
        
             
        
                                                 hwndChild[i] = CreateWindow (szChildClass[i], NULL,
        
                               WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
        
                               0, 0, 0, 0,
        
                              hwnd, (HMENU) i, hInstance, NULL) ;
        
                          }
        

                          cyChar = HIWORD (GetDialogBaseUnits ()) ;
        
                          SetTimer (hwnd, 1, 10, NULL) ;
        
                          return 0 ;
        
        
        
           case   WM_SIZE:
        
                          cxClient = LOWORD (lParam) ;
        
                          cyClient = HIWORD (lParam) ;
        
        
        
                          for (i = 0 ; i < 4 ; i++)
        
                  MoveWindow (hwndChild[i],     (i % 2) * cxClient / 2,
        
                                           (i > 1) * cyClient / 2,
        
                        cxClient / 2, cyClient / 2, TRUE) ;
        
                                  return 0 ;
        
        
        
           case   WM_TIMER:
        
                          for (i = 0 ; i < 4 ; i++)
        
                                         SendMessage (hwndChild[i], WM_TIMER, wParam, lParam) ;
        
        
        
                          return 0 ;
        
        
        
         case   WM_CHAR:
        
                          if (wParam == '\x1B')
        
                                                 DestroyWindow (hwnd) ;
        
        
        
                          return 0 ;
        
        
        
           case   WM_DESTROY:
        
                          KillTimer (hwnd, 1) ;
        
                          PostQuitMessage (0) ;
        
                          return 0 ;
        
   }
        
    return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
在这个程序里实际上没有什么我们没见过的东西。主窗口建立四个子窗口,每个子窗口占据显示区域的一个象限。主窗口还设定一个Windows定时器并发送WM_TIMER消息给四个子窗口中的每一个。

通常一个Windows程序应该保留足够的信息以便在WM_PAINT消息处理期间重建其窗口中的内容。MULTI1没有这么做,既然它绘制和清除窗口的速度如此之快,所以我认为那是不必要的。

WndProc2中的质数产生器的效率并不很高,但是有效。如果一个数除了1和它自身以外没有别的因子,那么这个数就是质数。当然,要检查一个数是否是质数并不要求使用小于被检查数的所有数来除这个数并检查余数,而只需使用所有小于被检查数的平方根的数。平方根计算是发表浮点数的原因,否则,该程序将是完全依据整数的程序。

MULTI1程序没有什么不好的地方。使用Windows定时器是在Windows的早期(和目前)版本中模拟多任务的一种好方法,然而,定时器的使用有时限制了程序的速度。如果程序可以在WM_TIMER消息处理中更新它的所有窗口而还有时间剩余下来的话,那就意味着它并没有充分利用我们的机器资源。

一种可能的解决方案是在单个WM_TIMER消息处理期间进行两次或者更多次的更新,但是到底多少次呢?这不得不依赖于机器的速度,而有很大的变动性。您当然不会想编写一个只能适用于25MHz的386或50MHz的486或100-GHz的Pentium VII上的程序吧。

多线程解决方案


让我们来看一看关于这个程序设计问题的一种多线程解决方案。如程序20-3 MULTI2所示。

程序20-3 MULTI2 
        
MULTI2.C
        
/*---------------------------------------------------------------------------
        
  MULTI2.C --   Multitasking Demo
        
                                                         (c) Charles Petzold, 1998
        
----------------------------------------------------------------------------*/
        
#include <windows.h>
        
#include <math.h>
        
#include <process.h>
        

typedef struct
        
{
        
           HWND          hwnd ;
        
           int           cxClient ;
        
           int           cyClient ;
        
           int           cyChar ;
        
           BOOL bKill ;
        
}
        
PARAMS, *PPARAMS ;
        
LRESULT APIENTRY WndProc (HWND, UINT, WPARAM, LPARAM) ;
        
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
        
                   PSTR szCmdLine, int iCmdShow)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -