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的更多相关文章

  1. malware analysis、Sandbox Principles、Design && Implementation

    catalog . 引言 . sandbox introduction . Sandboxie . seccomp(short for secure computing mode): API级沙箱 . ...

  2. 【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 ...

  3. Windows Kernel Security Training Courses

    http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...

  4. Jena 简介:通过 Jena Semantic Web Framework 在 Jave 应用程序中使用 RDF 模型

    简介: RDF 越来越被认为是表示和处理半结构化数据的一种极好选择.本文中,Web 开发人员 Philip McCarthy 向您展示了如何使用 Jena Semantic Web Toolkit,以 ...

  5. Android Security

    Android Security¶ 确认签名¶ Debug签名: $ jarsigner -verify -certs -verbose bin/TemplateGem.apk sm 2525 Sun ...

  6. [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 ...

  7. 人机交互技术 Week 11_Data gathering

    Summary: Different Kinds of Requirements Functional requirements Data requirements Environmental req ...

  8. WPF Wonders: Transformations (and Robots!)

    indows Presentation Framework (WPF) gets a lot of mileage out of being layered on top of DirectX, in ...

  9. 转:一个C语言实现的类似协程库(StateThreads)

    http://blog.csdn.net/win_lin/article/details/8242653 译文在后面. State Threads for Internet Applications ...

随机推荐

  1. LTE Air interface Channels-----http://www.rfwireless-world.com/Tutorials/LTE-logical-transport-physical-channels.html

    LTE technology works based on three channel types viz. logical channel,transport channel and physica ...

  2. 在为ListView设置adapter时出错

    为listView设置adapter,代码如下: SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.m ...

  3. ionic单页面应用中微信分享的问题总结

    首先说一下 ionic 是单页面应用,也就是说整个项目就有一个index.html, 那么问题就就来了, 如果我们不同的页面要分享给大家的是不同的链接和图片,应该怎么去做呢? 这就是我们今天要总结的东 ...

  4. 动态拼接linq 使用Expression构造动态linq语句

    最近在做动态构造linq语句,从网上找了很多,大多数,都是基于一张表中的某一个字段,这样的结果,从网上可以搜到很多.但如果有外键表,需要动态构造外键表中的字段,那么问题来了,学挖掘机哪家强?哦,不是, ...

  5. iOS中 HTTP/Socket/TCP/IP通信协议详解

    // OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. ...

  6. Eclipse中10个最有用的快捷键组合

    Eclipse中10个最有用的快捷键组合 (转) 一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升. ...

  7. JS中的数据类型检测

    JavaScript的数据类型分为两类:原始类型(primitive type)和对象类型(object type).原始类型有5种,分别是:数字(Number).字符串(String).布尔值(Bo ...

  8. SIGKDD历年Best Papers

    作者:我爱机器学习原文链接:SIGKDD历年Best Papers SIGKDD(Data Mining)(1997-2016) 年份 标题 一作 一作单位 2016 FRAUDAR: Boundin ...

  9. C++模拟C#事件委托机制(二)

    原文 来自于http://www.cnblogs.com/netssfy/archive/2010/02/02/1662056.html 为了解决非法地址访问的冲突,首先需要知道发生该错误的原因是什么 ...

  10. C++ 类模板的使用

    从事C++挺久了,在前段时看书时,发现高手,都是在写模板无,泛型编程,顿感差距.自己连模板都没有写,于是就小小的研究了下模板的用法. 模板简而言之就是对某此对象的相同方法,或处理方式,进行归纳,总结, ...