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. @@identity的使用

    -- ============================================= -- Author: Qiuhua,Huang -- Create date: 08/09/2012 ...

  2. 第一篇:Retrofit主要类UML图

    2016-05-06 16:07:09 1.先上一张Retrofit的代码结构图: 可以看到,Retrofit自身的结构很简单,代码量也不是很大.红色框部分是一些注解类,就是一些标记. 简单的看一下客 ...

  3. 常用OpenLDAP命令

    ldappasswd -x -D "cn=Manager,dc=clouderachina,dc=com" -W "uid=mis,ou=Group,dc=clouder ...

  4. powershell玩转SQL SERVER所有版本

    微软发布了最新的powershell for sql server 2016命令行客户端库.文章介绍了与之相关的实用方法. powershell 传教士 原创文章 2016-06-05, 2016-1 ...

  5. java中Jbutton常用设置

    . 对JButton大小的设置     ——因为JButen是属于小器件类型的,所以一般的setSize不能对其惊醒大小的设置,所以一般我们用     button.setPreferredSize( ...

  6. 与焊接厂交流——从生产角度出发的PCB设计心得

    上周的时候,去了趟加工厂盯电路板的焊接进度.然后在闲余的时候,跟焊接厂的工程师交流了一下,工程师从生产的角度,说了几个值得注意的事项: 1.元件的焊盘应该要窄长,不能过宽.因为,在过机表贴时,焊盘上的 ...

  7. greendao 3.1.0在android studio中配置

    1 项目根build.gradle classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0' 2 app中build.gradle apply p ...

  8. AFN断点续传思路

  9. cookie 保存导航菜单的展开状态

    菜单展开状态保存,最开始是用session来存的,用session存没点击一次菜单就会多次访问后台页面,影响页面加载速度,后来改用js的cookie来存:代码如下 //获取cookie         ...

  10. 控制台手动编译Qt5程序

    转自:http://www.cnblogs.com/csulennon/p/4479236.html 在上一篇随笔中已经搭建好了Qt5的的开发环境,并且通过Qt Creator自动构建了一个视窗程序. ...