照《windows编程大师》弄的小DEMO,出问题解决不了,求救~~
几乎照着上面的代码敲了,但运行时,接口正确申请了,Surface也成功,但就是DDSURFACEDESC2内的iPitch值,系统给我填充是6000多的值,我是256色的模式的,8位一个像素,这里应该是设置的分辨率才对呀,我直接运行书本的Demo,该值正常是640,是分辨率的宽度,实在不明白,什么原因导致的,请各位看下我的代码,帮我分析下。谢谢先了。
main.cpp
------------------------------------------------
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include "resource.h"
#include <stdlib.h>
#include <string>
#include "Win.h"
#include "Game.h"
#include "DirectX.h"
using namespace std;
#pragma comment(lib,"winmm.lib")
LRESULT CALLBACK WinProc(HWND hWnd, UINT uInt, WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance_app;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdShow)
{
MSG msg;
CWin wc(TEXT("WNDCLASS"),WinProc);
//wc.wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.Create(TEXT("My Game"), 0, 0, 1680, 1050,NULL,NULL,WS_POPUP | WS_VISIBLE/*, LoadMenu(wc.GetHinstance(), MAKEINTRESOURCE(IDR_MENU))*/);
//SetMenu(wc.GetHwnd(), LoadMenu(wc.GetHinstance(), MAKEINTRESOURCE(IDR_MENU)));
CDirectX draw;
draw.Init(wc.GetHwnd());
//draw.SetDisplayMode(1680, 1050);
/*if (!draw.hasError())
{
draw.SetDisplayMode(1680,1050);
}*/
while (true)
{
if ((GetAsyncKeyState(VK_ESCAPE) & 0x8000) ? 1 : 0)
{
SendMessage(wc.GetHwnd(), WM_CLOSE, 0, 0);
}
if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
draw.LockAndDraw(1680, 1050);
}
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
PlaySound(MAKEINTRESOURCE(APP_SOUND), hInstance_app, SND_ASYNC | SND_RESOURCE | SND_LOOP);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd,&ps);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_QUIT:
break;
case WM_DESTROY:
PlaySound(NULL, hInstance_app, SND_PURGE);
PlaySound(MAKEINTRESOURCE(APP_END_SOUND), hInstance_app, SND_RESOURCE | SND_SYNC);
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_OPEN:
{
MessageBox(hWnd, TEXT("ID_FILE_OPEN"), TEXT("点中的菜单项"), MB_OK);
/*CGame game;
game.init(3000);
while (true)
{
unsigned long tick = GetTickCount();
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
break;
game.earse(hWnd);
game.move();
game.draw(hWnd);
while (GetTickCount() - tick < 30);
}*/
break;
}
case ID_FILE_CLOSE:
MessageBox(hWnd, TEXT("ID_FILE_CLOSE"), TEXT("点中的菜单项"), MB_OK);
SendMessage(hWnd, WM_QUIT, 0, 0);
break;
case ID_FILE_SAVE:
MessageBox(hWnd, TEXT("ID_FILE_SAVE"), TEXT("点中的菜单项"), MB_OK);
break;
case ID_FILE_EXIT:
MessageBox(hWnd, TEXT("ID_FILE_EXIT"), TEXT("点中的菜单项"), MB_OK);
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
case ID_HELP_ABOUT:
MessageBox(hWnd, TEXT("ID_HELP_ABOUT"), TEXT("点中的菜单项"), MB_OK);
break;
default:
break;
}
case WM_KEYDOWN:
{
}
break;
default:
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
win.h
________________________________________
#pragma once
#include <windows.h>
#include <windowsx.h>
class CWin
{
public:
WNDCLASSEX wndclass;
private:
wchar_t WindowClassName[256];
HWND hWnd;
HINSTANCE hInst;
public:
CWin(wchar_t *pClassNmae, WNDPROC WndProc);
~CWin();
bool Create(LPCTSTR lpWindowName, int X, int Y, int nWidth, int nHeight, HMENU hMenu = NULL, DWORD dwExStyle = NULL, DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE,
HWND hWndParent = NULL, LPVOID lpParam = NULL);
HWND GetHwnd() const;
HINSTANCE GetHinstance() const;
};
win.cpp
----------------------------------------------------------
#include "Win.h"
CWin::CWin(wchar_t *pClassName, WNDPROC WndProc)
{
lstrcpyW(WindowClassName,pClassName);
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.cbClsExtra = NULL;
wndclass.cbWndExtra = NULL;
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
wndclass.lpszClassName = WindowClassName;
wndclass.hInstance = hInst;
wndclass.lpszMenuName = NULL;
wndclass.lpfnWndProc = WndProc;
wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
}
CWin::~CWin()
{
}
bool CWin::Create(LPCTSTR lpWindowName, int X, int Y, int nWidth, int nHeight, HMENU hMenu, DWORD dwExStyle, DWORD dwStyle, HWND hWndParent, LPVOID lpParam)
{
if (!(RegisterClassEx(&wndclass)))
{
return false;
}
if (!(hWnd = CreateWindowEx(dwExStyle, WindowClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInst, lpParam)))
{
return false;
}
//ShowWindow(hWnd, WS_VISIBLE);
//UpdateWindow(hWnd);
return true;
}
HINSTANCE CWin::GetHinstance() const
{
return hInst;
}
HWND CWin::GetHwnd() const
{
return hWnd;
}
Directx.h
-------------------------------------------------------
#pragma once
#include "ddraw.h"
class CDirectX
{
public:
CDirectX();
~CDirectX();
CDirectX& Init(HWND hWnd);
bool hasError();
void SetDisplayMode(DWORD iWidth,DWORD iHeight);
void LockAndDraw(int widht,int height);
private:
bool isError;
PALETTEENTRY PTNColor[256];
DDSURFACEDESC2 ddsd;
public:
LPDIRECTDRAW7 lpDraw;
LPDIRECTDRAWPALETTE lpPalette;
LPDIRECTDRAWSURFACE7 lpSurface;
};
directx.cpp
-----------------------------------------------------
#include "DirectX.h"
CDirectX::CDirectX()
{
lpDraw = nullptr;
isError = false;
lpSurface = nullptr;
lpPalette = nullptr;
}
CDirectX::~CDirectX()
{
if (lpPalette)
{
lpPalette->Release();
lpPalette = nullptr;
}
if (lpSurface)
{
lpSurface->Release();
lpSurface = nullptr;
}
if (lpDraw)
{
lpDraw->Release();
lpDraw = nullptr;
}
}
CDirectX& CDirectX::Init(HWND hWnd)
{
if (FAILED(DirectDrawCreateEx(NULL, (void**)&lpDraw, IID_IDirectDraw7, NULL)))
{
isError = true;
return *this;
}
lpDraw->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
lpDraw->SetDisplayMode(1680, 1050, 8, NULL, NULL);
/*DWORD errl = lpDraw->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
switch (errl)
{
case DDERR_EXCLUSIVEMODEALREADYSET:
MessageBox(hWnd, L"DDERR_EXCLUSIVEMODEALREADYSET", L"DDERR_EXCLUSIVEMODEALREADYSET", MB_OK);
break;
case DDERR_HWNDALREADYSET:
MessageBox(hWnd, L"DDERR_HWNDALREADYSET", L"DDERR_HWNDALREADYSET", MB_OK);
break;
case DDERR_HWNDSUBCLASSED:
MessageBox(hWnd, L"DDERR_HWNDSUBCLASSED", L"DDERR_HWNDSUBCLASSED", MB_OK);
break;
case DDERR_INVALIDOBJECT:
MessageBox(hWnd, L"DDERR_INVALIDOBJECT", L"DDERR_INVALIDOBJECT", MB_OK);
break;
case DDERR_INVALIDPARAMS:
MessageBox(hWnd, L"DDERR_INVALIDPARAMS", L"DDERR_INVALIDPARAMS", MB_OK);
break;
case DDERR_OUTOFMEMORY:
MessageBox(hWnd, L"DDERR_OUTOFMEMORY", L"DDERR_OUTOFMEMORY", MB_OK);
break;
case DD_OK:
MessageBox(hWnd, L"DD_OK", L"DD_OK", MB_OK);
break;
default:
MessageBox(hWnd, L"UNKNOWN", L"UNKNOWN", MB_OK);
break;
}*/
/*DWORD err = lpDraw->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, PTNColor, &lpPalette, NULL);
switch (err)
{
case DDERR_INVALIDOBJECT:
MessageBox(hWnd, L"DDERR_INVALIDOBJECT", L"DDERR_INVALIDOBJECT", MB_OK);
break;
case DDERR_NOCOOPERATIVELEVELSET:
MessageBox(hWnd, L"DDERR_NOCOOPERATIVELEVELSET", L"DDERR_NOCOOPERATIVELEVELSET", MB_OK);
break;
case DDERR_OUTOFMEMORY:
MessageBox(hWnd, L"DDERR_OUTOFMEMORY", L"DDERR_OUTOFMEMORY", MB_OK);
break;
case DDERR_UNSUPPORTED:
MessageBox(hWnd, L"DDERR_UNSUPPORTED", L"DDERR_UNSUPPORTED", MB_OK);
break;
case DD_OK:
MessageBox(hWnd, L"DD_OK", L"DD_OK", MB_OK);
default:
MessageBox(hWnd, L"UNKNOWN", L"UNKNOWN", MB_OK);
break;
}*/
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
lpDraw->CreateSurface(&ddsd, &lpSurface, NULL);
for (size_t i = 1; i != 255; ++i)
{
PTNColor[i] = { rand() % 256, rand() % 256, rand() % 256, PC_NOCOLLAPSE };
}
PTNColor[0] = { 0, 0, 0, PC_NOCOLLAPSE };
PTNColor[255] = { 0, 0, 0, PC_NOCOLLAPSE };
if (FAILED(lpDraw->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, PTNColor, &lpPalette, NULL)))
{
isError = true;
return *this;
}
lpSurface->SetPalette(lpPalette);
return *this;
}
void CDirectX::LockAndDraw(int width,int height)
{
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
lpSurface->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
int mempitch = ddsd.lPitch;
UCHAR *buffer = (UCHAR*)ddsd.lpSurface;
wchar_t log[256];
memset(log, 0, sizeof(log));
wsprintf(log, L"mempithc:%d\r\n", mempitch);
OutputDebugString(log);
for (int i = 0; i != 1000; ++i)
{
int color = rand() % 256;
int x = rand() % width;
int y = rand() % height;
/*memset(log, 0, sizeof(log));
wsprintf(log, L"%d\r\n", x);
OutputDebugString(log);*/
buffer[x + y * mempitch] = color;
}
lpSurface->Unlock(NULL);
Sleep(30);
}
bool CDirectX::hasError()
{
return isError;
}
void CDirectX::SetDisplayMode(DWORD iWidth,DWORD iHeight)
{
lpDraw->SetDisplayMode(iWidth, iHeight, 8, NULL, NULL);
}
就这么多了,字数都不超5000的小DEMO,不知道什么原因出错。红字那里值异常。