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. zabbix-agent配置文件说明

    zabbix-agent配置文件:/etc/zabbix/zabbix_agentd.conf Server=zabbix server IP,网关IP hostname=本机IP ServerAct ...

  2. DataTable数据导出CSV文件

    public static void SaveAsExcel(DataTable dt1) { //System.Windows.Forms.SaveFileDialog sfd = new Syst ...

  3. Leetcode 详解(valid plindrome)

    Question: Given a string, determine if it is a palindrome, considering only alphanumeric characters ...

  4. 显示隐藏文件 .DS_Store文件

    1. mac为了保护系统文件和减少对用户的干扰,提高用户体验,将一些系统文件隐藏了起来,如hosts配置文件,.DS_Store文件 (Desktop Services Store),.localiz ...

  5. linux 网卡问题 Device eth0 does not seem to be present,delaying initialization.

    Device eth0 does not seem to be present,delaying initialization. 网上搜索后才发现原因所在:原来vmware在复制了虚拟机后会自动生成一 ...

  6. Bootstrap <基础七>按钮

    任何带有 class .btn 的元素都会继承圆角灰色按钮的默认外观.但是 Bootstrap 提供了一些选项来定义按钮的样式,具体如下表所示: 以下样式可用于<a>, <butto ...

  7. 《Pro Express.js》学习笔记——Express服务启动常规七步

    Express服务启动常规七步 1.       引用模块 var express=require('express'), compression=require('compression'), bo ...

  8. MicroERP软件更新记录1.1

    MicroERP软件更新记录 最新版本:1.1 1.增加固定资产检修.租赁.转移记录 2.增加产品质检单 3.增加零售单(收银台) 4.支持各种主流关系型数据库 5.完善了数据字典,如加入原材料材质. ...

  9. 高斯过程(gaussian process)

    Definition 1. A Gaussian Process is a collection of random variables, any finite number of which hav ...

  10. Android 振动器

    今天介绍一下Android的振动器Vibrator,有三个方法来控制手机振动: 1.void vibrate(long milliseconds):控制手机振动milliseconds毫秒. 2.vo ...