sehsum.c
来自「一本已经绝版的好书」· C语言 代码 · 共 189 行
C
189 行
/*************************************************************
Module name: SEHSum.C
Notices: Copyright (c) 1995-1997 Jeffrey Richter
*************************************************************/
#include "..\CmnHdr.H" /* See Appendix C. */
#include <windows.h>
#include <windowsx.h>
#include <limits.h>
#include <process.h> // For _beginthreadex
#include <tchar.h>
#include "Resource.H"
/////////////////////////////////////////////////////////////
// An example of calling Sum for uNum = 0 through 9
// uNum: 0 1 2 3 4 5 6 7 8 9 ...
// Sum: 0 1 3 6 10 15 21 28 36 45 ...
UINT Sum (UINT uNum) {
if (uNum == 0)
return(0);
// Call Sum recursively.
return(uNum + Sum(uNum - 1));
}
/////////////////////////////////////////////////////////////
long FilterFunc (DWORD dwExceptionCode) {
// Assume that we do not know how to handle the exception;
// tell the system to continue to search for an SEH
// handler.
long lRet = EXCEPTION_CONTINUE_SEARCH;
if (dwExceptionCode == STATUS_STACK_OVERFLOW) {
// If the exception raised is a stack overflow,
// we do know how to handle it.
lRet = EXCEPTION_EXECUTE_HANDLER;
}
return(lRet);
}
/////////////////////////////////////////////////////////////
// The separate thread that is responsible for calculating the
// sum. I use a separate thread for the following reasons:
// 1. A separate thread gets its own 1 MB of stack space.
// 2. A thread can be notified of a stack overflow only once.
// 3. The stack's storage is freed when the thread exits.
DWORD WINAPI SumThreadFunc (PVOID p) {
// The parameter, p, is really a UINT containing
// the number of integers to sum.
UINT uSumNum = (UINT) p;
// uSum contains the summation of the numbers
// from 0 through uSumNum. If the sum cannot be calculated,
// a sum of UINT_MAX is returned.
UINT uSum = UINT_MAX;
__try {
// To catch the stack overflow exception, we must
// execute the Sum function while inside an SEH block.
uSum = Sum(uSumNum);
}
__except (FilterFunc(GetExceptionCode())) {
// If we get in here, it's because we have trapped
// a stack overflow. We can now do whatever is
// necessary to gracefully continue execution.
// This sample application has nothing to do, so
// no code is placed in this exception handler block.
}
// The thread's exit code is the sum of the first uSumNum
// numbers, or UINT_MAX if a stack overflow occurred.
return(uSum);
}
/////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus,
LPARAM lParam) {
// Associate an icon with the dialog box.
chSETDLGICONS(hwnd, IDI_SEHSUM, IDI_SEHSUM);
return(TRUE);
}
/////////////////////////////////////////////////////////////
void Dlg_OnCommand (HWND hwnd, int id,
HWND hwndCtl, UINT codeNotify) {
UINT uSumNum, uSum;
BOOL fTranslated;
DWORD dwThreadId;
HANDLE hThread;
switch (id) {
case IDC_CALC:
// Get the number of integers the user wants to sum.
uSumNum = GetDlgItemInt(hwnd, IDC_SUMNUM,
&fTranslated, FALSE);
// Create a thread (with its own stack) that is
// responsible for performing the summation.
hThread = chBEGINTHREADEX(NULL, 0, SumThreadFunc,
(PVOID) uSumNum, 0, &dwThreadId);
// The thread's exit code is the resulting summation.
// We must first wait for the thread to terminate.
WaitForSingleObject(hThread, INFINITE);
// Now we can get the thread's exit code.
GetExitCodeThread(hThread, (PDWORD) &uSum);
// Finally, we close the handle to the thread so
// that the system can destroy the thread object.
CloseHandle(hThread);
// Update the dialog box to show the result.
if (uSum == UINT_MAX) {
// If the thread's exit code is UINT_MAX, a stack
// overflow occurred. Update the dialog box
// and display a message box.
SetDlgItemText(hwnd, IDC_ANSWER, __TEXT("Error"));
chMB(__TEXT("The number is too big, ")
__TEXT("please enter a smaller number"));
} else {
// The sum was calculated successfully;
// update the dialog box.
SetDlgItemInt(hwnd, IDC_ANSWER, uSum, FALSE);
}
break;
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}
/////////////////////////////////////////////////////////////
BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
}
return(FALSE);
}
/////////////////////////////////////////////////////////////
int WINAPI _tWinMain (HINSTANCE hinstExe,
HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) {
chWARNIFUNICODEUNDERWIN95();
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SUMMATION),
NULL, Dlg_Proc);
return(0);
}
//////////////////////// End Of File ////////////////////////
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?