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

📄 prntwait.c

📁 侯捷先生翻译的书籍《Win32多线程程序设计》的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * PrntWait.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This is from Chapter 3, Listing 3-4
 *
 * Demonstrate background printing and
 * using MsgWaitForMultipleObjects to
 * wait for threads to exit.
 */

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include "resource.h"
#include "MtVerify.h"

//
// Macro definitions
//
#define WM_SHOWBITMAP   WM_APP
#define WM_THREADCOUNT  WM_APP+1

#define MAX_PRINT_JOBS  64


//
// Structures
//
typedef struct
{   // Information passed to background thread for printing
    HWND hDlg;
    HWND hWndParent;
    HDC hDc;
    BOOL bPrint;    // TRUE if printing;
    char szText[256];
} ThreadPrintInfo;

//
// Global variables
//
HANDLE hInst;
HBITMAP gbmpDisplay;
RECT gDisplayRect;

int gNumPrinting = 0;

// Handle to each created thread
HANDLE gPrintJobs[64];

// Height of bitmap returned by DrawText
int iHeight;

// HWND of the dialog so other threads can find it.
HWND hDlgMain;


//
// Function declarations
//
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hWnd, unsigned msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK PrintDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL PrintDlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam);
void PrintDlg_OnCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify);
void PrintDlg_OnPaint(HWND hwnd);
void PrintText(HWND hwndParent, char *pszText);
void PrintToDisplay(HWND hwndParent, char *pszText);
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
DWORD WINAPI BackgroundPrintThread(LPVOID pVoid);


///////////////////////////////////////////////////////////
//
//      WinMain
//
// Main entry point of application. This will be a
// dialog based app, not a normal window, so this
// routine acts a little differently than "normal".
//
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG     msg;
    HWND    hWnd;
    WNDCLASS wc;
    BOOL    quit;
    int     exitCode;

    hInst = hInstance;
    if (!hPrevInstance)
    {
        memset(&wc, 0, sizeof(wc));
        wc.lpfnWndProc  = MainWndProc;
        wc.hInstance    = hInstance;
        wc.hIcon        = LoadIcon (hInstance, "GenIco");
        wc.hCursor      = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground= GetSysColorBrush(COLOR_BACKGROUND);
        wc.lpszMenuName = "PRINTING_MENU";
        wc.lpszClassName= "PrintDlgClass";
        if (!RegisterClass(&wc))
            return FALSE;
    }


    hWnd = CreateWindow(
        "PrintDlgClass",
        "Printing Hands-On",
        WS_OVERLAPPED|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU,
        CW_USEDEFAULT, // At this point we do not want to
        0,             //  show the window until we know
        0,             //  how big the Dialog Box is so
        0,             //  that we can fit the main window
        NULL,          //  around it.
        NULL,
        hInstance,
        NULL);

    hDlgMain = CreateDialog(hInst,
                    MAKEINTRESOURCE(IDD_PRINT),
                    hWnd, PrintDlgProc);

    ShowWindow(hWnd, nCmdShow);
    ShowWindow(hDlgMain, SW_SHOW);

    quit = FALSE;
    exitCode = 0;
    while (!quit || gNumPrinting > 0)
    {   // Wait for next message or object being signaled
        DWORD   dwWake;
        dwWake = MsgWaitForMultipleObjects(
                                gNumPrinting,
                                gPrintJobs,
                                FALSE,
                                INFINITE,
                                QS_ALLEVENTS);

        if (dwWake >= WAIT_OBJECT_0 && dwWake < WAIT_OBJECT_0 + gNumPrinting)
        {   // Object has been signaled
            // Reorder the handle array so we do not leave
            // empty slots. Take the handle at the end of
            // the array and move it into the now-empty slot.
            int index = dwWake - WAIT_OBJECT_0;
            gPrintJobs[index] = gPrintJobs[gNumPrinting-1];
            gPrintJobs[gNumPrinting-1] = 0;
            gNumPrinting--;
            SendMessage(hDlgMain, WM_THREADCOUNT, gNumPrinting, 0L);
        } // end if
        else if (dwWake == WAIT_OBJECT_0 + gNumPrinting)
        {
            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {   // Get Next message in queue
                if(hDlgMain == NULL || !IsDialogMessage(hDlgMain,&msg))
                {
                    if (msg.message == WM_QUIT)
                    {
                        quit = TRUE;
                        exitCode = msg.wParam;
                        break;
                    } // end if
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            } // end while
        }
    } // end while
    return (exitCode);  /* Returns the value from PostQuitMessage */
}


LRESULT CALLBACK MainWndProc(HWND hWnd, unsigned msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
        break;

    case WM_COMMAND:

        switch (wParam)
        {
        case IDM_ABOUT:
            DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);
            break;
        case IDM_EXIT:
            PostQuitMessage(0);
            break;
        default:
            return (DefWindowProc(hWnd, msg, wParam, lParam));
        }

    case WM_SETFOCUS:
        // ensure that the Dialog Box has the focus
        SetFocus(hDlgMain);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);

    }
    return 0;
}


LRESULT CALLBACK PrintDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hDlg);
        hDlgMain = NULL;
        break;
        
    case WM_DESTROY:
        return TRUE;
        break;

    case WM_SHOWBITMAP:
        if (gbmpDisplay)
            DeleteObject(gbmpDisplay);

        gDisplayRect = *(RECT*)wParam;
        gbmpDisplay = (HBITMAP) lParam;
        InvalidateRect(hDlgMain, NULL, TRUE);
        break;

    case WM_THREADCOUNT:
        {
            HMENU hMenu;

            // Show number of threads
            SetDlgItemInt(hDlg, IDC_EDIT_THREADS, wParam, FALSE);

            // Enable/Disable File.Exit menu
            hMenu = GetMenu(GetParent(hDlg));
            EnableMenuItem(hMenu, IDM_EXIT, wParam != 0);
            break;
        } // end case

    HANDLE_MSG(hDlg, WM_INITDIALOG, PrintDlg_OnInitDialog);
    HANDLE_MSG(hDlg, WM_COMMAND, PrintDlg_OnCommand);
    HANDLE_MSG(hDlg, WM_PAINT, PrintDlg_OnPaint);

    default:
        return (FALSE);
    }

    return 0;
}

BOOL PrintDlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
{
    RECT rect;

    // Size parent to fit this dialog
    GetWindowRect(hwndDlg, &rect); 
    SetWindowPos(GetParent(hwndDlg),NULL,
        0,0,
        rect.right-rect.left,
        rect.bottom-rect.top+GetSystemMetrics(SM_CYMENU)
            +GetSystemMetrics(SM_CYCAPTION),
        SWP_NOMOVE | SWP_NOZORDER);

    SetDlgItemInt(hwndDlg, IDC_EDIT_THREADS, 0, FALSE);

    return TRUE;
}

void PrintDlg_OnCommand(HWND hDlg, int id,HWND hwndCtl, UINT codeNotify)
{
    char szText[256];

    switch (id)
    {
    case IDC_PRINT:

⌨️ 快捷键说明

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