1.Basic Techniques and Knowledge
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:
#define STRICT
#include<windows.h>
#include<tchar.h>
#include<assert.h>
#pragma comment(linker,"/subsystem:\"windows\"" ) const TCHAR szOperation[]=_T("open");
const TCHAR szAddress[]=_T("www.helloworld.com"); int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR lpCmd,int nShow)
{
HINSTANCE hRslt=ShellExecute(NULL,szOperation,szAddress,NULL,NULL,SW_SHOWNORMAL);
assert(hRslt>(HINSTANCE)HINSTANCE_ERROR);
return ;
}
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
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <assert.h>
void CenterText(HDC hDC, int x, int y, LPCTSTR szFace,
LPCTSTR szMessage, int point)
{
HFONT hFont = CreateFont(
-point * GetDeviceCaps(hDC, LOGPIXELSY) / ,
, , , 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(, , 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");
//#pragma comment(linker, "-merge:.rdata=.text")
//#pragma comment(linker, "-align:512") #pragma comment(linker, "/entry:WinMainCRTStartup") extern "C" void WinMainCRTStartup()
{
HDC hDC = GetDC(NULL);
assert(hDC);
CenterText(hDC, GetSystemMetrics(SM_CXSCREEN) / ,
GetSystemMetrics(SM_CYSCREEN) / ,
szFace, szMessage, );
ReleaseDC(NULL, hDC);
ExitProcess();
}
这个程序研究了一些时间,用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.
1.Basic Techniques and Knowledge的更多相关文章
- malware analysis、Sandbox Principles、Design && Implementation
catalog . 引言 . sandbox introduction . Sandboxie . seccomp(short for secure computing mode): API级沙箱 . ...
- 【Repost】A Practical Intro to Data Science
Are you a interested in taking a course with us? Learn about our programs or contact us at hello@zip ...
- Windows Kernel Security Training Courses
http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...
- Jena 简介:通过 Jena Semantic Web Framework 在 Jave 应用程序中使用 RDF 模型
简介: RDF 越来越被认为是表示和处理半结构化数据的一种极好选择.本文中,Web 开发人员 Philip McCarthy 向您展示了如何使用 Jena Semantic Web Toolkit,以 ...
- Android Security
Android Security¶ 确认签名¶ Debug签名: $ jarsigner -verify -certs -verbose bin/TemplateGem.apk sm 2525 Sun ...
- [C5] Andrew Ng - Structuring Machine Learning Projects
About this Course You will learn how to build a successful machine learning project. If you aspire t ...
- 人机交互技术 Week 11_Data gathering
Summary: Different Kinds of Requirements Functional requirements Data requirements Environmental req ...
- WPF Wonders: Transformations (and Robots!)
indows Presentation Framework (WPF) gets a lot of mileage out of being layered on top of DirectX, in ...
- 转:一个C语言实现的类似协程库(StateThreads)
http://blog.csdn.net/win_lin/article/details/8242653 译文在后面. State Threads for Internet Applications ...
随机推荐
- Debian/Ubuntu/CentOS VPS安装Net-Speeder并优化
安装过程: CentOS安装 wget --no-check-certificate https://gist.github.com/LazyZhu/dc3f2f84c336a08fd6a5/raw/ ...
- html 中自动换行的实现方式
1,<div type="word-wrap: break-word;word-break:break-all;"> </div> 2, <div t ...
- 关于EM,REM,PX的几点注意
px是绝对单位,不支持IE的缩放,em是相对单位. em指字体高,任意浏览器的默认字体高都是16px.所以未经调整的浏览器都符合: 1em=16px.那么12px=0.75em, 10px=0.625 ...
- Struts2 Action下面的Method调用方法
1. 在struts.xml中加入<constant name="struts.enable.DynamicMethodInvocation" value="tru ...
- 计划任务,机器码与注册码,Web服务
01.计划任务的客户端配置 TScheduleTask 辅助结构内容: TScheduleRecord<ScheduleTask.pas> TScheduleRecord.Schedule ...
- hdoj 1576
//1Y真是爽啊 题意:要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). 分析:根据题意a=b*x a=m ...
- FTP Proxy Server
本文将在Linux环境下实现一个简单的FTP代理服务器,主要内容涉及FTP主动/被动模式和简单的Socket编程. 1. 主动模式和被动模式 FTP有两种模式,即主动模式(Active Mode)和被 ...
- git入门学习
初步学习笔记. 1.创建仓库:git init 仓库:个人理解为文件存放及版本追踪的容器,对应着一个目录,目录中包含用户的文件及git用来追踪文件版本的一系列文件. 新建并进入HelloWorld目录 ...
- leetcode日记 Combination sum IV
题目: Given an integer array with all positive numbers and no duplicates, find the number of possible ...
- c语言函数指针
#include <stdio.h> typedef void (*intFunc)(int i); void test1(int age) { printf("test1:%d ...