1.Basic Techniques and Knowledge

本文通过四个逐步进阶的示例程序,介绍了使用C/C++进行Windows编程的基础知识,从简单的浏览器调用到DirectDraw图形绘制,涵盖了窗口程序创建、直接绘图至桌面、全屏窗口程序及DirectDraw使用等内容。

1.1 BASIC WINDOWS PROGRAMMING IN C/C++

1.Hello World Version 1:Starting Your Browser

Let's get down now to the business of writing a basic Windows program in C.Here is our first windows program:

 1 #define STRICT
 2 #include<windows.h>
 3 #include<tchar.h>
 4 #include<assert.h>
 5 #pragma comment(linker,"/subsystem:\"windows\"" )
 6 
 7 const TCHAR szOperation[]=_T("open");
 8 const TCHAR szAddress[]=_T("www.helloworld.com");
 9 
10 int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR lpCmd,int nShow)
11 {
12     HINSTANCE hRslt=ShellExecute(NULL,szOperation,szAddress,NULL,NULL,SW_SHOWNORMAL);
13     assert(hRslt>(HINSTANCE)HINSTANCE_ERROR);
14     return 0;
15 }

If you could run this program,your browser would bring up a web page through a powerful Win32 API call,ShellExecute.

The program starts by defining a macro STRICT,which tells the windows include file to treat different object types differently,making it easier for the compiler to give programmers waring messages if they mix HANDLE with HINSTANCE,or HPEN with HBRUSH.if you hear a reader complaining that sample program certain books can't even compile,it is likely that the sample programs were not tested with the macro CTRICT defined.This happens because the newer version of Windows include files that turn STRICT on by default,while the older versions do not.

2.Hello World Version 2:Drawing Directly to Desktop

 1 #define STRICT
 2 #define WIN32_LEAN_AND_MEAN
 3 #include <windows.h>
 4 #include <tchar.h>
 5 #include <assert.h>
 6 void CenterText(HDC hDC, int x, int y, LPCTSTR szFace,
 7  LPCTSTR szMessage, int point)
 8 {
 9  HFONT hFont = CreateFont(
10  -point * GetDeviceCaps(hDC, LOGPIXELSY) / 72,
11  0, 0, 0, FW_BOLD, TRUE, FALSE, FALSE,
12  ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
13  PROOF_QUALITY, VARIABLE_PITCH, szFace);
14  assert(hFont);
15  HGDIOBJ hOld = SelectObject(hDC, hFont);
16  SetTextAlign(hDC, TA_CENTER | TA_BASELINE);
17  SetBkMode(hDC, TRANSPARENT);
18  SetTextColor(hDC, RGB(0, 0, 0xFF));
19  TextOut(hDC, x, y, szMessage, _tcslen(szMessage));
20  SelectObject(hDC, hOld);
21  DeleteObject(hFont);
22 }
23 const TCHAR szMessage[] = _T("Hello, World");
24 const TCHAR szFace[] = _T("Times New Roman");
25 //#pragma comment(linker, "-merge:.rdata=.text")
26 //#pragma comment(linker, "-align:512")
27 
28 #pragma comment(linker, "/entry:WinMainCRTStartup")
29 
30 extern "C" void WinMainCRTStartup()
31 {
32  HDC hDC = GetDC(NULL);
33  assert(hDC);
34  CenterText(hDC, GetSystemMetrics(SM_CXSCREEN) / 2,
35  GetSystemMetrics(SM_CYSCREEN) / 2,
36  szFace, szMessage, 72);
37  ReleaseDC(NULL, hDC);
38  ExitProcess(0);
39 }

这个程序研究了一些时间,用VC6.0编译,需在将原程序指定连接选项的方法改为 #pragma comment(linker, "/entry:WinMainCRTStartup"),表示将程序的入口点设置为自定义的WinMainCRTStartup;另外还需要将编译模式由Debug改为Release,具体的在菜单栏空白处点击右键,勾选“组建”,选择Release

 

3.Hello World Version 3:Create a Full-Screen Window

We will try to develop a simple object-ariented window program in C++ without the help of Microsoft Foundation Class.

Here is the header file for the KWindow class:

//win.h

#pragma once
class KWindow
{
 virtual void OnDraw(HDC hDC)
 {
 }
 virtual void OnKeyDown(WPARAM wParam, LPARAM lParam)
 {
 }
 virtual LRESULT WndProc(HWND hWnd, UINT uMsg,
 WPARAM wParam, LPARAM lParam);
 static LRESULT CALLBACK WindowProc(HWND hWnd,
 UINT uMsg, WPARAM wParam, LPARAM lParam);
 virtual void GetWndClassEx(WNDCLASSEX & wc);
public:
 HWND m_hWnd;
 KWindow(void)
 {
 m_hWnd = NULL;
 }
 virtual ~KWindow(void)
 {
 }
virtual bool CreateEx(DWORD dwExStyle,
 LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
 int x, int y, int nWidth, int nHeight, HWND hParent,
 HMENU hMenu, HINSTANCE hInst);
 bool RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst);
 virtual WPARAM MessageLoop(void);
 BOOL ShowWindow(int nCmdShow) const
 {
 return ::ShowWindow(m_hWnd, nCmdShow);
 }
 BOOL UpdateWindow(void) const
 {
 return ::UpdateWindow(m_hWnd);
 }
};

Here is the implementation for the KWindow class:

win.cpp

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include ".\win.h"
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg,
 WPARAM wParam, LPARAM lParam)
{
 switch( uMsg )
 {
 case WM_KEYDOWN:
 OnKeyDown(wParam, lParam);
 return 0;
 case WM_PAINT:
 {
 PAINTSTRUCT ps;
  BeginPaint(m_hWnd, &ps);
 OnDraw(ps.hdc);
 EndPaint(m_hWnd, &ps);
 }
 return 0;
 case WM_DESTROY:
 PostQuitMessage(0);
 return 0;
 }
 return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg,
 WPARAM wParam, LPARAM lParam)
{
 KWindow * pWindow;
 if ( uMsg == WM_NCCREATE )
 {
 assert( ! IsBadReadPtr((void *) lParam,
 sizeof(CREATESTRUCT)) );
 MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *)
 ((LPCREATESTRUCT) lParam)->lpCreateParams;
 pWindow = (KWindow *) (pMDIC->lParam);
 assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
 SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
 }
 else
 pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
 if ( pWindow )
 return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
 else
 return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
bool KWindow::RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst)
{
 WNDCLASSEX wc;
 if ( ! GetClassInfoEx(hInst, lpszClass, &wc) )
 {
 GetWndClassEx(wc);
 wc.hInstance = hInst;
 wc.lpszClassName = lpszClass;
 if ( !RegisterClassEx(&wc) )
 return false;
 }
 return true;
}
bool KWindow::CreateEx(DWORD dwExStyle,
 LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
 int x, int y, int nWidth, int nHeight, HWND hParent,
 HMENU hMenu, HINSTANCE hInst)
{
if ( ! RegisterClass(lpszClass, hInst) )
 return false;
 // use MDICREATESTRUCT to pass this pointer, support MDI child window
 MDICREATESTRUCT mdic;
 memset(& mdic, 0, sizeof(mdic));
 mdic.lParam = (LPARAM) this;
 m_hWnd = CreateWindowEx(dwExStyle, lpszClass, lpszName,
 dwStyle, x, y, nWidth, nHeight,
 hParent, hMenu, hInst, & mdic);
 return m_hWnd!=NULL;
}
void KWindow::GetWndClassEx(WNDCLASSEX & wc)
{
 memset(& wc, 0, sizeof(wc));
 wc.cbSize = sizeof(WNDCLASSEX);
 wc.style = 0;
 wc.lpfnWndProc = WindowProc;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hInstance = NULL;
 wc.hIcon = NULL;
 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 wc.lpszMenuName = NULL;
 wc.lpszClassName = NULL;
 wc.hIconSm = NULL;
}
WPARAM KWindow::MessageLoop(void)
{
 MSG msg;
 while ( GetMessage(&msg, NULL, 0, 0) )
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 return msg.wParam;
}

Here is our third version of"Hello,World",a normal window program version using C++:

Hello3.cpp

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include<windows.h>
#include<assert.h>
#include<tchar.h>

#include ".\win.h"

void CenterText(HDC hDC, int x, int y, LPCTSTR szFace,
 LPCTSTR szMessage, int point)
{
 HFONT hFont = CreateFont(
 -point * GetDeviceCaps(hDC, LOGPIXELSY) / 72,
 0, 0, 0, FW_BOLD, TRUE, FALSE, FALSE,
 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
 PROOF_QUALITY, VARIABLE_PITCH, szFace);
 assert(hFont);
 HGDIOBJ hOld = SelectObject(hDC, hFont);
 SetTextAlign(hDC, TA_CENTER | TA_BASELINE);
 SetBkMode(hDC, TRANSPARENT);
 SetTextColor(hDC, RGB(0, 0, 0xFF));
 TextOut(hDC, x, y, szMessage, _tcslen(szMessage));
 SelectObject(hDC, hOld);
 DeleteObject(hFont);
}


const TCHAR szMessage[]=_T("Hello,Word!");
const TCHAR szFace[]=_T("Times New Roman");
const TCHAR szHint[]=_T("Press ESC to quit.");
const TCHAR szProgram[]=_T("HelloWorld3");

class KHelloWindow:public KWindow
{
	void OnKeyDown(WPARAM wParam,LPARAM lParam)
	{
		if(wParam==VK_ESCAPE)
			PostMessage(m_hWnd,WM_CLOSE,0,0);
	}
	void OnDraw(HDC hDC)
	{
		TextOut(hDC,0,0,szHint,lstrlen(szHint));
		CenterText(hDC,GetDeviceCaps(hDC,HORZRES)/2,GetDeviceCaps(hDC,VERTRES)/2,
			szFace,szMessage,72);
	}
public:
};



int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR lpCmd,int nShow)
{
	KHelloWindow win;
	win.CreateEx(0,szProgram,szProgram,WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),
		NULL,NULL,hInst);
	win.ShowWindow(nShow);
	win.UpdateWindow();

	return win.MessageLoop();
	
}

 

Source code attachment:

zb_system/image/filetype/rar.png"" data_ue_src=""<#ZC_BLOG_HOST#>zb_system/image/filetype/rar.png""/>c1_hwv3.zip

4.Hello World Version 4:Drawing With DirectDraw

Microsoft's DirectDraw API,initially designed for high-performance game programing,allows programs to get even closer with a screen buffer and features offered by advanced display cards.

Here is a simple program using DirectDraw:

// Hello4.cpp
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <ddraw.h>
#include ".\win.h"

#pragma comment(lib,"ddraw.lib")

void CenterText(HDC hDC, int x, int y, LPCTSTR szFace,
 LPCTSTR szMessage, int point)
{
 HFONT hFont = CreateFont(
 -point * GetDeviceCaps(hDC, LOGPIXELSY) / 72,
 0, 0, 0, FW_BOLD, TRUE, FALSE, FALSE,
 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
 PROOF_QUALITY, VARIABLE_PITCH, szFace);
 assert(hFont);
 HGDIOBJ hOld = SelectObject(hDC, hFont);
 SetTextAlign(hDC, TA_CENTER | TA_BASELINE);
 SetBkMode(hDC, TRANSPARENT);
 SetTextColor(hDC, RGB(0, 0, 0xFF));
 TextOut(hDC, x, y, szMessage, _tcslen(szMessage));
 SelectObject(hDC, hOld);
 DeleteObject(hFont);
}

const TCHAR szMessage[] = _T("Hello, World !");
const TCHAR szFace[] = _T("Times New Roman");
const TCHAR szHint[] = _T("Press ESC to quit.");
const TCHAR szProgram[] = _T("HelloWorld4");
// Copy CenterText from Hello2.cpp
class KDDrawWindow : public KWindow
{
 LPDIRECTDRAW lpdd;
 LPDIRECTDRAWSURFACE lpddsprimary;
 void OnKeyDown(WPARAM wParam, LPARAM lParam)
 {
 if (wParam==VK_ESCAPE )
 PostMessage(m_hWnd, WM_CLOSE, 0, 0);
 }
 void Blend(int left, int right, int top, int bottom);
void OnDraw(HDC hDC)
 {
 TextOut(hDC, 0, 0, szHint, lstrlen(szHint));
 CenterText(hDC, GetSystemMetrics(SM_CXSCREEN)/2,
 GetSystemMetrics(SM_CYSCREEN)/2,
 szFace, szMessage, 48);
 Blend(80, 560, 160, 250);
 }
public:
 KDDrawWindow(void)
 {
 lpdd = NULL;
 lpddsprimary = NULL;
 }
 ~KDDrawWindow(void)
 {
 if ( lpddsprimary )
 {
 lpddsprimary->Release();
 lpddsprimary = NULL;
 }
 if ( lpdd )
 {
 lpdd->Release();
 lpdd = NULL;
 }
 }
  bool CreateSurface(void);
};
bool KDDrawWindow::CreateSurface(void)
{
 HRESULT hr;
 hr = DirectDrawCreate(NULL, &lpdd, NULL);
 if (hr!=DD_OK)
 return false;
 hr = lpdd->SetCooperativeLevel(m_hWnd,
 DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
 if (hr!=DD_OK)
 return false;
 hr = lpdd->SetDisplayMode(640, 480, 32);
 if (hr!=DD_OK)
 return false;
 DDSURFACEDESC ddsd;
 memset(& ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 ddsd.dwFlags = DDSD_CAPS;
 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 return lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)
 ==DD_OK;
}
void inline Blend(unsigned char *dest, unsigned char *src)
{
 dest[0] = (dest[0] + src[0])/2;
 dest[1] = (dest[1] + src[1])/2;
 dest[2] = (dest[2] + src[2])/2;
}
void KDDrawWindow::Blend(int left, int right,
 int top, int bottom)
{
 DDSURFACEDESC ddsd;
 memset(&ddsd, 0, sizeof(ddsd));
 ddsd.dwSize = sizeof(ddsd);
 HRESULT hr = lpddsprimary->Lock(NULL, &ddsd,
 DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
 assert(hr==DD_OK);
 unsigned char *screen = (unsigned char *)
 ddsd.lpSurface;
 for (int y=top; y<bottom; y++)
 {
 unsigned char * pixel = screen + y * ddsd.lPitch
 + left * 4;
 for (int x=left; x<right; x++, pixel+=4)
 if ( pixel[0]!=255 || pixel[1]!=255 ||
 pixel[2]!=255 ) // non white
 {
 ::Blend(pixel-4, pixel); // left
 ::Blend(pixel+4, pixel); // right
 ::Blend(pixel-ddsd.lPitch, pixel); // up
 ::Blend(pixel+ddsd.lPitch, pixel); // down
 }
 }
 lpddsprimary->Unlock(ddsd.lpSurface);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE,
 LPSTR lpCmd, int nShow)
{
 KDDrawWindow win;
 win.CreateEx(0, szProgram, szProgram,
 WS_POPUP,
 0, 0,
 GetSystemMetrics( SM_CXSCREEN ),
 GetSystemMetrics( SM_CYSCREEN ),
 NULL, NULL, hInst);
 win.CreateSurface();
 win.ShowWindow(nShow);
 win.UpdateWindow();
 return win.MessageLoop();
}

运行该程序,需要将第三个“Hello,World”程序中的”win.h“和”win.cpp“文件导入进来;另外,在主程序中需要添加 #pragma comment(lib,"ddraw.lib")语句,即导入DirectDraw支持的静态链接库文件,以及添加对CenterText函数的定义

Don't be discouraged if you've not touched the DirectDraw API yet;We will cover it in full detail in Chapter 18.

转载于:https://www.cnblogs.com/lanf/p/5092958.html

03-09
### Tree.js Library Information and Usage Examples Tree.js appears not directly mentioned within provided references. However, based on common knowledge about JavaScript libraries named `tree.js`, these typically provide functionalities for creating tree structures or visualizations. For a generic understanding of how such a library might work: #### Installation via npm Since the Node.js Package Manager (npm) is widely utilized for managing packages in projects[^1], one would likely install `tree.js` through npm if it were available as an npm package. ```bash npm install tree.js --save ``` This command installs the latest version of `tree.js` into your project's node_modules folder and adds it to dependencies in `package.json`. #### Basic Example Code Using Hypothetical Tree.js Features Assuming that `tree.js` offers functions to create nodes and trees along with methods to manipulate them: ```javascript // Importing the hypothetical tree.js module const Tree = require('tree.js'); // Creating root node let rootNode = new Tree.Node('root'); // Adding child nodes rootNode.addChild(new Tree.Node('child1')); rootNode.addChild(new Tree.Node('child2')); console.log(JSON.stringify(rootNode, null, 2)); ``` The above code snippet demonstrates initializing the library, constructing a simple binary tree structure starting from a root node, adding children under this parent node, and printing out its JSON representation. #### Properties Definition Similarity With Vue Components Props If comparing properties definition style between components like those found when working with frameworks such as Vue where objects define component props[^2], similar patterns may exist within configuration options passed during instantiation of elements inside `tree.js`. For instance, ```javascript new Tree({ id: 'unique-id', label: 'Root Label' }); ``` Here, specific attributes are assigned values much alike defining reactive data points or settings required by instantiated objects. #### Performance Considerations When Handling Large Data Structures When dealing with extensive datasets represented hierarchically using `tree.js`, performance optimizations could involve techniques discussed regarding efficient handling of large-scale computations over partitioned blocks of columnar-stored records[^3]. Although contextually different, principles around caching strategies, parallel processing capabilities offered by underlying hardware architectures remain relevant considerations while scaling up applications built upon complex nested models managed by `tree.js`.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值