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 ...
随机推荐
- asp.netajax开发应用心得-accordation控件的事件处理
今天,再次运行以前的项目时,发现按钮的单击事件不起作用了,加了断点之后发现根本没有触发该事件.... 按照网上找到的答案,有的说把控件删掉重新拖拽一个进去,虽然以前也遇到过控件失效,重新拖拽有效的时候 ...
- 160809208沈昊辰c语言程序设计实验选择结构设计
<C语言程序设计>实验报告 学 号 160809208 姓 名 沈昊辰 专业.班 计科16-2班 学 期 2016-2017 第1学期 指导教师 黄俊莲 吴喆 实验地点 C区二层机房 ...
- Python future模块
今天看到了Pyhon中的模块__future__,查了一下资料,感觉这个module很有用. 从python2.1开始以后, 当一个新的语言特性首次出现在发行版中时候, 如果该新特性与以前旧版本pyt ...
- linux中用户的主目录~
-在Linux中代表用户主目录 对一般用户,-表示/home/(用户名) 对于root用户,-表示/root 如果要查看-的真实面貌,可以先进入-目录,然后用pwd -P命令查看-的绝对路径 cd ~ ...
- Log4J详解
Log4J 简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...
- Windows下QT Creator工程中添加文件夹
在QT项目,常常会有很多头文件和源文件,但是QT Creator中却没有添加文件夹的功能,造成项目代码混乱. 下面是建立文件的步骤: 1.打开工程目录,在目录下建立文件夹,如建立文件SerialP ...
- 资源:Python for Windows
http://win32com.goermezer.de/content/blogsection/7/284/ 一个网站,有各种Windows 下使用 Python 的脚本示例,很不错,有待继续挖掘. ...
- Apache RewriteRule
1.Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言.可基 于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式.如果要想用到rewrite模块 ...
- tcp的简单介绍
为什么会有TCP/IP协议 在 世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人 的口音,让他们无法合作 ...
- C++多线程3
#include "stdafx.h" #include <windows.h> #include <process.h> int g_count; ; u ...