Jump to content
  • Advertisement
  • entries
    743
  • comments
    1924
  • views
    584377

Win32 insanity ruling my life

Sign in to follow this  
Aardvajk

190 views

It is going "well". The hand-coded map editor is working, but I am slightly stunned by how much code it takes to do something relatively simple.

So far we have a randomly filled map that can be scrolled around the client area of the window, and the code so far (sorry, GameDev servers) is:


#include

#include "resource.h"
#include "general.h"

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
int Register(HINSTANCE HIn);

CBitmap Back;
CBitmap Bmp;
CMap Map;

int XSc=0,YSc=0;

int WINAPI WinMain(HINSTANCE HIn,HINSTANCE,LPSTR CmdLine,int Show)
{
HWND Hw;
MSG Msg;

if(!Register(HIn)) return 0;

Hw=CreateWindowEx(WS_EX_CLIENTEDGE,"MyWin","Map 2.0",WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
0,0,600,600,
GetDesktopWindow(),NULL,HIn,NULL);

if(Hw==NULL) return 0;

ShowWindow(Hw,Show); UpdateWindow(Hw); SetFocus(Hw);

PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE);
while(Msg.message!=WM_QUIT)
{
if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}

return static_cast<int>(Msg.wParam);
}

void OnCreate(HWND Hw)
{
Map.Random(20,20);

HDC Dc=GetDC(Hw);
Back.Create(Dc,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
ReleaseDC(Hw,Dc);

Bmp.LoadFromFile("C:\\Graphics\\Block.bmp");
}

void OnSize(HWND Hw,bool Normal)
{
RECT Cr; GetClientRect(Hw,&Cr);

int Mw=Map.Width()*48;
int Mh=Map.Height()*48;

SCROLLINFO Si;
Si.cbSize=sizeof(SCROLLINFO);
Si.fMask=SIF_RANGE|SIF_PAGE;
Si.nMin=0;

Si.nMax=Mw;
Si.nPage=Cr.right;
SetScrollInfo(Hw,SB_HORZ,&Si,TRUE);

Si.nMax=Mh;
Si.nPage=Cr.bottom;
SetScrollInfo(Hw,SB_VERT,&Si,TRUE);

Si.fMask=SIF_POS;
GetScrollInfo(Hw,SB_HORZ,&Si);
XSc=Si.nPos;

Si.fMask=SIF_POS;
GetScrollInfo(Hw,SB_VERT,&Si);
YSc=Si.nPos;

InvalidateRect(Hw,NULL,false);
}

void OnHorzScroll(HWND Hw,int Type,int Pos)
{
RECT Cr; GetClientRect(Hw,&Cr);

int New;

switch(Type)
{
case SB_PAGEUP : New=XSc-Cr.right; break;
case SB_PAGEDOWN : New=XSc+Cr.right; break;
case SB_LINEUP : New=XSc-48; break;
case SB_LINEDOWN : New=XSc+48; break;
case SB_THUMBTRACK : New=Pos; break;
default : New=XSc;
}

XSc=New;

SCROLLINFO Si;
Si.cbSize=sizeof(SCROLLINFO);
Si.fMask=SIF_PAGE;
GetScrollInfo(Hw,SB_HORZ,&Si);

if(XSc<0) XSc=0;
if(XSc>(Map.Width()*48)-int(Si.nPage)) XSc=Map.Width()*48-Si.nPage;

Si.fMask=SIF_POS;
Si.nPos=XSc;
SetScrollInfo(Hw,SB_HORZ,&Si,TRUE);

InvalidateRect(Hw,NULL,false);
}

void OnVertScroll(HWND Hw,int Type,int Pos)
{
RECT Cr; GetClientRect(Hw,&Cr);

int New;

switch(Type)
{
case SB_PAGEUP : New=YSc-Cr.bottom; break;
case SB_PAGEDOWN : New=YSc+Cr.bottom; break;
case SB_LINEUP : New=YSc-48; break;
case SB_LINEDOWN : New=YSc+48; break;
case SB_THUMBTRACK : New=Pos; break;
default : New=YSc;
}

YSc=New;

SCROLLINFO Si;
Si.cbSize=sizeof(SCROLLINFO);
Si.fMask=SIF_PAGE;
GetScrollInfo(Hw,SB_VERT,&Si);

if(YSc<0) YSc=0;
if(YSc>(Map.Height()*48)-int(Si.nPage)) YSc=Map.Height()*48-Si.nPage;

Si.fMask=SIF_POS;
Si.nPos=YSc;
SetScrollInfo(Hw,SB_VERT,&Si,TRUE);

InvalidateRect(Hw,NULL,false);
}

void OnPaint(HWND Hw)
{
RECT Cr; GetClientRect(Hw,&Cr);

int Wt=Cr.right;
int Ht=Cr.bottom;

PAINTSTRUCT Ps;
HDC ScrDc=BeginPaint(Hw,&Ps);

HBRUSH B=CreateHatchBrush(HS_DIAGCROSS,RGB(192,192,192));
HDC Dc=CreateCompatibleDC(ScrDc);
SelectObject(Dc,Back.Handle());

FillRect(Dc,&Cr,B);

DeleteObject(B);

int Mw=Map.Width()*48;
int Mh=Map.Height()*48;

int Gx=0,Gy=0;

if(Wt>Mw) Gx=(Wt-Mw)/2;
if(Ht>Mh) Gy=(Ht-Mh)/2;

int Mx=XSc/48,My=YSc/48;
int Dx=XSc%48,Dy=YSc%48;

for(int Y=0;Y<(Cr.bottom/48)+48;++Y)
{
for(int X=0;X<(Cr.right/48)+48;++X)
{
if(Mx+X {
if(Map(X+Mx,Y+My))
{
HDC Mem=CreateCompatibleDC(Dc);
SelectObject(Mem,Bmp.Handle());

BitBlt(Dc,(X*48)-Dx+Gx,(Y*48)-Dy+Gy,Bmp.Width(),Bmp.Height(),Mem,0,0,SRCCOPY);

DeleteDC(Mem);
}
else
{
RECT R;

R.left=(X*48)-Dx+Gx;
R.top=(Y*48)-Dy+Gy;
R.right=R.left+48;
R.bottom=R.top+48;

B=CreateHatchBrush(HS_DIAGCROSS,RGB(120,120,120));
FillRect(Dc,&R,B);
DeleteObject(B);
}
}
}
}

BitBlt(ScrDc,0,0,Cr.right,Cr.bottom,Dc,0,0,SRCCOPY);

DeleteDC(Dc);
EndPaint(Hw,&Ps);
}

void OnDestroy(HWND Hw)
{
PostQuitMessage(0);
}

LRESULT CALLBACK WndProc(HWND Hw,UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE: OnCreate(Hw); break;
case WM_PAINT: OnPaint(Hw); break;
case WM_DESTROY: OnDestroy(Hw); break;
case WM_SIZE: OnSize(Hw,wParam==SIZE_RESTORED); break;
case WM_HSCROLL: OnHorzScroll(Hw,LOWORD(wParam),HIWORD(wParam)); break;
case WM_VSCROLL: OnVertScroll(Hw,LOWORD(wParam),HIWORD(wParam)); break;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_EXIT: DestroyWindow(Hw); break;

default: return DefWindowProc(Hw,Msg,wParam,lParam);
}

default: return DefWindowProc(Hw,Msg,wParam,lParam);
}

return 0;
}

int Register(HINSTANCE HIn)
{
WNDCLASSEX Wc;

Wc.cbSize=sizeof(WNDCLASSEX);
Wc.style=0;
Wc.lpfnWndProc=WndProc;
Wc.cbClsExtra=0;
Wc.cbWndExtra=0;
Wc.hInstance=HIn;
Wc.hIcon=LoadIcon(HIn,MAKEINTRESOURCE(IDI_SMALL));
Wc.hCursor=LoadCursor(NULL,IDC_ARROW);
Wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
Wc.lpszMenuName=MAKEINTRESOURCE(IDC_WIN);
Wc.lpszClassName="MyWin";
Wc.hIconSm=LoadIcon(HIn,MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&Wc);
}





CBitmap is defined elsewhere but I thought I'd pasted enough code for one day.

Scrollbars do my head in. I've never seen so much work to do something quite straightforward. Still, never mind. I think this project could be far better structured but I'm just going to hammer on for now and hopefully learn enough that next time I write a Windows app, I'll be able to structure it better from the start.

All a learning curve. Very steep.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!