2022-12-16 18:49:16 chip
Page 2469
📢 PUBLIC
December 14 2022
The goal of this project is to create a Direct2D pixel shader with
the fewest lines of code possible and NO FRAMEWORKS .
Window Shell
I need a minimal Window project. This is as small as I could make
it without making the project more difficult than it needed.
TEXT PxlShader.cpp :
#include <Windows.h>
#include "Handles.h"
#include "ChipLib.h"
HINSTANCE ghInst;
DWORD DbgFilter;
static const WCHAR ClassName[]= { L"PxlShader" };
#define SIGNATURE_PXLSHADER 0xCD190001
class PxlShader {
public:
static PxlShader *Ptr(void *pObj);
static PxlShader *Ptr(HWND hWnd);
static int Create(HWND &hWnd);
private:
PxlShader(void);
~PxlShader(void);
int Create2(void);
static INT_PTR CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm);
LRESULT WndProc2(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm);
int MsgCreate(HWND hWnd);
int MsgDestroy(void);
int MsgClose(void);
int MsgTimer(void);
int MsgPaint(void);
//Data
DWORD Signature;
HWND hWnd;
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR pArgs, int nShow) {
int Err= ERR_OK;
HWND hWnd= 0;
ghInst= hInst;
MemCreate();
TmpBufCreate(16*1024*1024);
if(IsErr(Err= PxlShader::Create(hWnd))) {
Err= Error(Err,"WinMain: Unable to create the main window.");
} else {
while(hWnd && IsWindow(hWnd)) {
MSG Msg;
GetMessage(&Msg,hWnd,0,0);
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
TmpBufDestroy();
MemDestroy();
if(IsErr(MemReport()))
MessageBox(0,L"PxlShader: Memory error.",L"PxlShader",MB_OK|MB_SETFOREGROUND);
return(Err);
}
void ConsolePrint(DWORD Type, const WCHAR *Text) {
TXT Out(0,0,"%s\r\n",Text);
OutputDebugString(Out);
}
PxlShader::PxlShader(void) {
Signature= SIGNATURE_PXLSHADER;
}
PxlShader::~PxlShader(void) {
Signature|= SIGNATURE_INVALID;
}
PxlShader *PxlShader::Ptr(void *pObj) {
PxlShader *pPxl= (PxlShader*)pObj;
if(!pObj || IsBadPtr(pObj,sizeof(*pPxl),BADPTR_RW) || pPxl->Signature!=SIGNATURE_PXLSHADER)
pPxl= 0;
return(pPxl);
}
PxlShader *PxlShader::Ptr(HWND hWnd) {
if(!hWnd || !IsWindow(hWnd))
return(0);
return(Ptr((void*)GetWindowLongPtr(hWnd,GWLP_USERDATA)));
}
int PxlShader::Create(HWND &hWnd) {
int Err= ERR_OK;
PxlShader *pPxl= new PxlShader;
if(!pPxl) {
Err= Error(ERR_NO_MEM,"PxlShader:Create: NoMem");
} else if(IsErr(Err= pPxl->Create2())) {
delete pPxl;
} else {
hWnd= pPxl->hWnd;
}
return(Err);
}
int PxlShader::Create2(void) {
int Err= ERR_OK;
ATOM hWndClass;
WNDCLASS WndClass;
RECT R= { 100,100,500,300 };
Zero(WndClass);
WndClass.style= CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc= WndProc;
WndClass.hInstance= ghInst;
WndClass.lpszClassName= ClassName;
DWORD style= WS_OVERLAPPEDWINDOW|WS_VISIBLE;
if(!(hWndClass= RegisterClass(&WndClass))) {
Err= Error(ERR_SYSCREATE,"PxlShader:Create2: Unable to register the main window class.");
} else if(!(hWnd= CreateWindow(ClassName,L"PxlShader",style,R.left,R.top,RWID(R),RHGT(R),0,0,ghInst,(LPVOID)this))) {
Err= Error(ERR_SYSCREATE,"PxlShader:Create2: Unable to create the main window.");
}
return(Err);
}
INT_PTR CALLBACK PxlShader::WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm) {
INT_PTR Result= 0;
PxlShader *pPxl= 0;
if(Msg==WM_CREATE) {
CREATESTRUCT *pCreate= (CREATESTRUCT*)lParm;
pPxl= Ptr(pCreate->lpCreateParams);
} else {
pPxl= Ptr(hWnd);
}
if(!pPxl) {
Result= DefWindowProc(hWnd,Msg,wParm,lParm);
} else {
Result= pPxl->WndProc2(hWnd,Msg,wParm,lParm);
}
return(Result);
}
LRESULT PxlShader::WndProc2(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm) {
LRESULT Result= 0;
switch(Msg) {
case WM_CREATE: Result= MsgCreate(hWnd); break;
case WM_DESTROY: Result= MsgDestroy(); break;
case WM_CLOSE: Result= MsgClose(); break;
case WM_TIMER: Result= MsgTimer(); break;
case WM_PAINT: Result= MsgPaint(); break;
default: Result= DefWindowProc(hWnd,Msg,wParm,lParm); break;
}
return(Result);
}
int PxlShader::MsgCreate(HWND _hWnd) {
hWnd= _hWnd;
SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)this);
return(1);
}
int PxlShader::MsgDestroy(void) {
SetWindowLongPtr(hWnd,GWLP_USERDATA,0);
delete this;
return(1);
}
int PxlShader::MsgClose(void) {
DestroyWindow(hWnd);
return(1);
}
int PxlShader::MsgTimer(void) {
return(1);
}
int PxlShader::MsgPaint(void) {
PAINTSTRUCT Pnt;
if(BeginPaint(hWnd,&Pnt)) {
HBRUSH hbrFill= CreateSolidBrush(RGB(20,30,40));
FillRect(Pnt.hdc,&Pnt.rcPaint,hbrFill);
DeleteObject(hbrFill);
EndPaint(hWnd,&Pnt);
}
ValidateRect(hWnd,0);
return(1);
}
//EOF: PXLSHADER.CPP
Additional library directories:
$(SolutionDir)LibExt/Win$(PlatformName)$(Configuration);
$(SolutionDir)Lib/Win$(PlatformName)$(Configuration)
I am using my ChipLib for my convenience, not yours. It is
too large and complex to explain or provide, so you will just have
to fill in the missing pieces. Hint: Print() Error() Warn().
BE AWARE: ChipLib includes a version of new() and MemAlloc()
that clears all allocated memory to zero. This lets me skip explicitly
setting everything to zero in the constructors and calling
ZeroMemory() after every call to malloc. This may cause some
unexpected bugs if any of my code is recompiled without ChipLib.
This should create a small, blank window filled with blue-gray.
WebV7 (C)2018 nlited | Rendered by tikope in 56.421ms | 3.133.109.251