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

📄 kpad.cpp

📁 WTL开发的一个写字板程序 ,很有借鉴意义
💻 CPP
字号:
// kPad.cpp : main source file for kPad.exe
//

#include "stdafx.h"

#define SIDEBAR_WIDTH 21
#define SIDEBAR_FONT  "Comic Sans MS"

// font size array
const static int font_size[] = 
		{6, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72};

#include <atlframe.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include <atlctrlw.h>
#include <atlmisc.h>
#include <AtlCtrlx.h>
#include <atlprint.h>

#include "resource.h"
#include "AtlAux2.h"

#include "common.h"
#include "option.h"
#include "CmdBar.h"
#include "kFlatCombo.h"
#include "kFontCombo.h"
#include "kColorPickerButton.h"
#include "OptionDlg.h"
#include "kSheetView.h"
#include "kSheet.h"
#include "aboutdlg.h"
#include "MainFrm.h"

CAppModule _Module;

__declspec( thread ) _Context g_Context = {0};

class CMessageLoop2 : public CMessageLoop
{
public:
	int Run()
	{
		BOOL bDoIdle = TRUE;
		int nIdleCount = 0;
		BOOL bRet;

		for(;;)
		{
			while(!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE) && bDoIdle)
			{
				if(!OnIdle(nIdleCount++))
					bDoIdle = FALSE;
			}

			bRet = ::GetMessage(&m_msg, NULL, 0, 0);

			if(bRet == -1)
			{
				ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
				continue;	// error, don't process
			}
			else if(!bRet)
			{
				ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
				break;		// WM_QUIT, exit message loop
			}

			if(!PreTranslateMessage(&m_msg))
			{
				::TranslateMessage(&m_msg);
				::DispatchMessage(&m_msg);
			}

			// ! change
			if(IsIdleMessage2(&m_msg))
			{
				bDoIdle = TRUE;
				nIdleCount = 0;
			}
		}

		return (int)m_msg.wParam;
	}

	static BOOL IsIdleMessage2(MSG* pMsg)
	{
		// These messages should NOT cause idle processing
		switch(pMsg->message)
		{
		case WM_MOUSEMOVE:
		case WM_NCMOUSEMOVE:
		case WM_PAINT:
		case 0x0118:	// WM_SYSTIMER (caret blink)
		// ! change
		case WM_TIMER:
			return FALSE;
		}
		return TRUE;
	}	
};

class CKPadThreadManager
{
public:
	// thread init param
	struct _RunData
	{
		LPTSTR lpstrCmdLine;
		int nCmdShow;
	};

	// thread proc
	static DWORD WINAPI RunThread(LPVOID lpData)
	{
		// !
		CMessageLoop2 theLoop;
		_Module.AddMessageLoop(&theLoop);

		_RunData* pData = (_RunData*)lpData;
		CMainFrame wndFrame;

		g_Context.m_frame = &wndFrame;

		RECT *prc = 0;
		RECT rc = {0, 0, 0, 0};		

		{
			CRegKey key;			
			if (ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, kPadRegKey))
			{						
				DWORD dwType = REG_BINARY;
				DWORD dwSize = sizeof RECT;
				if ((ERROR_SUCCESS == RegQueryValueEx(key, _T("WindowRect"), 0, &dwType, (BYTE *)&rc, &dwSize))
						&& (REG_BINARY == dwType) && (sizeof(RECT) == dwSize) && !IsRectEmpty(&rc)) 
					prc = &rc;
			}
		}
		
		if(wndFrame.CreateEx(0, prc) == NULL)
		{
			ATLTRACE(_T("Frame window creation failed!\n"));
			return 0;
		}

		///////////////////////
		
		if(pData->lpstrCmdLine[0] == 0)
		{		
		}
		else	// file name specified at the command line
		{
			// strip quotes (if any)
			TCHAR* pCmd = pData->lpstrCmdLine;
			if(pCmd[0] == '"')
			{
				pCmd++;
				for(int i = 0; i < lstrlen(pCmd); i++)
				{
					if(pCmd[i] == '"')
					{
						pCmd[i] = 0;
						break;
					}
				}
			}

			//	get full path and file name
			TCHAR sPath[MAX_PATH];
			LPTSTR sFile = NULL;
			::GetFullPathName(pCmd, MAX_PATH, sPath, &sFile);
			
			// open file
			wndFrame.DoFileOpen(sPath);	
		}

		///////////////////////

		wndFrame.ShowWindow(pData->nCmdShow);
		::SetForegroundWindow(wndFrame);	// Win95 needs this
		delete pData;

		int nRet = theLoop.Run();

		_Module.RemoveMessageLoop();
		return nRet;
	}

	DWORD m_dwCount;
	HANDLE m_arrThreadHandles[MAXIMUM_WAIT_OBJECTS - 1];

	CKPadThreadManager() : m_dwCount(0)
	{ }

// Operations
	DWORD AddThread(LPTSTR lpstrCmdLine, int nCmdShow)
	{
		if(m_dwCount == (MAXIMUM_WAIT_OBJECTS - 1))
		{
			::MessageBox(NULL, _T("ERROR: Cannot create ANY MORE threads!!!"), _T("kPad"), MB_OK);
			return 0;
		}

		_RunData* pData = new _RunData;
		pData->lpstrCmdLine = lpstrCmdLine;
		pData->nCmdShow = nCmdShow;
		DWORD dwThreadID;
		HANDLE hThread = ::CreateThread(NULL, 0, RunThread, pData, 0, &dwThreadID);
		if(hThread == NULL)
		{
			::MessageBox(NULL, _T("ERROR: Cannot create thread!!!"), _T("kPad"), MB_OK);
			return 0;
		}

		m_arrThreadHandles[m_dwCount] = hThread;
		m_dwCount++;
		return dwThreadID;
	}

	void RemoveThread(DWORD dwIndex)
	{
		::CloseHandle(m_arrThreadHandles[dwIndex]);
		if(dwIndex != (m_dwCount - 1))
			m_arrThreadHandles[dwIndex] = m_arrThreadHandles[m_dwCount - 1];
		m_dwCount--;
	}

	int Run(LPTSTR lpstrCmdLine, int nCmdShow)
	{
		MSG msg;
		// force message queue to be created
		::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

		AddThread(lpstrCmdLine, nCmdShow);

		int nRet = m_dwCount;
		DWORD dwRet;
		while(m_dwCount > 0)
		{
			dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles, FALSE, INFINITE, QS_ALLINPUT);

			if(dwRet == 0xFFFFFFFF)
				::MessageBox(NULL, _T("ERROR: Wait for multiple objects failed!!!"), _T("kPad"), MB_OK);
			else if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1))
				RemoveThread(dwRet - WAIT_OBJECT_0);
			else if(dwRet == (WAIT_OBJECT_0 + m_dwCount))
			{
				::GetMessage(&msg, NULL, 0, 0);
				if(msg.message == WM_USER)
					AddThread("", SW_SHOWNORMAL);
				else
					::MessageBeep((UINT)-1);
			}
			else
				::MessageBeep((UINT)-1);
		}

		return nRet;
	}
};

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to 
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

#if (_WIN32_IE >= 0x0300)
	INITCOMMONCONTROLSEX iccx;
	iccx.dwSize = sizeof(iccx);
	iccx.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES; 
	BOOL bRet = ::InitCommonControlsEx(&iccx);
	bRet;
	ATLASSERT(bRet);
#else
	::InitCommonControls();
#endif

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	HINSTANCE hInstRich = ::LoadLibrary(CRichEditCtrl::GetLibraryName());
	ATLASSERT(hInstRich != NULL);

	CKPadThreadManager mgr;
	int nRet = mgr.Run(lpstrCmdLine, nCmdShow);

	::FreeLibrary(hInstRich);
	_Module.Term();
	::CoUninitialize();

	return nRet;
}

⌨️ 快捷键说明

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