几乎照着上面的代码敲了,但运行时,接口正确申请了,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); 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);
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; 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,不知道什么原因出错。红字那里值异常。