Quelltext /~heha/hs/Kalenderpuzzle.zip/src/kp.cpp

/* Kalenderpuzzle, erzgebirgische Spielerei aus Holz,
 lasergeschnitten und -beschriftet
 231102	angefangen
*/

#include "kp.h"

/************
 * Globales *
 ************/

HINSTANCE ghInstance;
HWND ghMainWnd;
HWND hGain,hOffs;		// Amplitude und Offset (Schieberegler am oberen Rand)
CONFIG Config;
TCHAR StdMBoxTitle[64];
TCHAR sDecimal[2];	// je nach Windows-Einstellung
TCHAR sNegativeSign[2];
TCHAR sPositiveSign[2];

void _cdecl DebugPrintf(const char*s,...) {
 char buf[256];
 va_list va;
 va_start(va,s);
 _vsnprintf(buf,elemof(buf),s,va);
 OutputDebugStringA(buf);
}

/****************
 * aus WUTILS.C *
 ****************/

//Win32-typische Strukturen mit DWORD-Ausrichtung initialisieren
void _fastcall InitStruct(LPVOID p, UINT len) {
 ZeroMemory(p,len);
 *(UINT*)p=len;
}

int vMBox(HWND Wnd, LPCTSTR Text, DWORD Type, va_list va) {
 TCHAR buf[256];
 if (IS_INTRESOURCE(Text)) {
  TCHAR s[256];
  LoadString(ghInstance,(UINT)(DWORD_PTR)Text,s,elemof(s));
  Text = s;
 }
 DWORD e;
 if (Type&MB_ErrorText) e = va_arg(va,DWORD);
 int l = _vsntprintf(buf,elemof(buf),Text,va);
 if (Type&MB_ErrorText) {
  TCHAR s[120];
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,e,0,s,elemof(s),0);
  _sntprintf(buf+l,elemof(buf)-l,T("\n\n%s"),s);
 }
 if (Type&MB_Sound) MessageBeep(Type&MB_ICONMASK);
 return MessageBox(Wnd,buf,StdMBoxTitle,Type&~MB_Sound);
}

int _cdecl MBox(HWND Wnd, LPCTSTR Text, DWORD Type, ...) {
 va_list va;
 va_start(va,Type);
 return vMBox(Wnd,Text,Type,va);
}

/****************
 * Hauptfenster *
 ****************/
 
void LoadConfig(void) {
 HKEY key;
 if (RegOpenKey(HKEY_CURRENT_USER,T("Software\\h#s\\kp"),&key)) return;
 DWORD size=sizeof Config;
 RegQueryValueEx(key,T("Config"),NULL,NULL,(LPBYTE)&Config,&size);
 RegCloseKey(key);
 if (Config.ShowCmd) {
  WINDOWPLACEMENT wp;
  wp.length=sizeof wp;
  GetWindowPlacement(ghMainWnd,&wp);
  Config.WndPos.toRect(wp.rcNormalPosition);
  wp.showCmd=Config.ShowCmd;
  SetWindowPlacement(ghMainWnd,&wp);
 }
}
 
void SaveConfig(void) {
 WINDOWPLACEMENT wp;
 wp.length=sizeof wp;
 GetWindowPlacement(ghMainWnd,&wp);
 if (wp.showCmd) {
  Config.WndPos=wp.rcNormalPosition;
  Config.ShowCmd=wp.showCmd;
 }
 HKEY key;
 if (RegCreateKey(HKEY_CURRENT_USER,T("Software\\h#s\\kp"),&key)) return;
 TCHAR s[64];	// zuerst eine Klartext-Beschreibung setzen
 RegSetValueEx(key,NULL,0,REG_SZ,(LPBYTE)s,LoadString(ghInstance,1,s,elemof(s))*sizeof(TCHAR));
 RegSetValueEx(key,T("Config"),0,REG_BINARY,(LPBYTE)&Config,sizeof Config);
 RegCloseKey(key);
}

void ReposChilds() {
 HDWP wpi=BeginDeferWindowPos(4);
 EndDeferWindowPos(wpi);
}

static byte gMonat,gTag;
static HFONT ghFont;

void tagplus(int tagdelta) {
 if (Config.flags&2) {
  int m=gMonat, t=gTag+tagdelta;
  while (t<1) --m, t+=31;
  while (t>31) ++m, t-=31;
  while (m<1) m+=12;
  while (m>12) m-=12;
  gMonat=m, gTag=t;
 }else{
  SYSTEMTIME st;
  GetLocalTime(&st);
  st.wMonth=gMonat, st.wDay=gTag;
  FILETIME ft;
  SystemTimeToFileTime(&st,&ft);
  *((__int64*)&ft)+=tagdelta*24*(__int64)36000000000;
  FileTimeToSystemTime(&ft,&st);
  gMonat=(byte)st.wMonth, gTag=(byte)st.wDay;
 }
 solver.solve(gMonat,gTag,Config.flags);
 InvalidateRect(ghMainWnd,0,true);
}

LRESULT CALLBACK MainWndProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
 switch (Msg) {
  case WM_CREATE: {
   ghMainWnd=Wnd;
   HMENU SysMenu=GetSystemMenu(Wnd,FALSE);
   SendMessage(Wnd,WM_WININICHANGE,0,0);
   SendMessage(Wnd,WM_QUERYOPEN,0,0);	// Titel setzen
   LoadConfig();
   ghFont=CreateFont(20,0,0,0,0,0,0,0,DEFAULT_CHARSET,OUT_TT_ONLY_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_SWISS,0);
   CheckMenuItem(GetMenu(Wnd),0x40,Config.flags&1?MF_CHECKED:MF_UNCHECKED);
   CheckMenuItem(GetMenu(Wnd),0x50,Config.flags&2?MF_CHECKED:MF_UNCHECKED);
   SYSTEMTIME st;
   GetLocalTime(&st);
   solver.solve(gMonat=(byte)st.wMonth,gTag=(byte)st.wDay,Config.flags);
  }break;
  
  case WM_WININICHANGE: {	// TODO: Windows-Funktion FormatFloat o.ä. gefunden!
   GetProfileString(T("intl"),T("sDecimal"),     T("."),sDecimal,     elemof(sDecimal));
   GetProfileString(T("intl"),T("sNegativeSign"),T("-"),sNegativeSign,elemof(sNegativeSign));
   GetProfileString(T("intl"),T("sPositiveSign"),T(""), sPositiveSign,elemof(sPositiveSign));
  }return 0;

  case WM_SIZE: {
   if (wParam!=SIZE_MINIMIZED) {
    ReposChilds();
   }
  }break;
  
  case WM_PAINT: {
   PAINTSTRUCT ps;
   HDC dc=BeginPaint(Wnd,&ps);
   RECT rc;
   GetClientRect(Wnd,&rc);
   rc.right-=rc.left;
   rc.bottom-=rc.top;
   SetMapMode(dc,MM_ISOTROPIC);
   SetWindowExtEx(dc,32*8,32*8,0);
   SetViewportExtEx(dc,rc.right,rc.bottom,0);
   SetWindowOrgEx(dc,16*7,16*7,0);
   SetViewportOrgEx(dc,rc.right>>1,rc.bottom>>1,0);
   SetRect(&rc,-16,-16,8*32-16,8*32-16);
   FillRect(dc,&rc,GetStockBrush(LTGRAY_BRUSH));
   SYSTEMTIME st;
   GetLocalTime(&st);
   SetTextAlign(dc,TA_CENTER|TA_BASELINE);
   HFONT ofont=SelectFont(dc,ghFont);
   TCHAR s[8];
   st.wDay=1;	// Den Ersten des Monats gibt es immer.
   int i=0; do{
    int x=i%6, y=i/6;
    st.wMonth=++i;
    int n=GetDateFormat(LOCALE_USER_DEFAULT,0,&st,T("MMM"),s,elemof(s))-1;
    SetRect(&rc,x*32,y*32,(x+1)*32,(y+1)*32);
    ExtTextOut(dc,x*32+16,y*32+22,ETO_NUMERICSLOCAL|ETO_OPAQUE,&rc,s,n,0);
   }while(i<12);
   i=0; do{
    int x=i%7, y=i/7+2;
    st.wDay=++i;
    int n=GetDateFormat(LOCALE_USER_DEFAULT,0,&st,T("d"),s,elemof(s))-1;
    SetRect(&rc,x*32,y*32,(x+1)*32,(y+1)*32);
    ExtTextOut(dc,x*32+16,y*32+22,ETO_NUMERICSLOCAL|ETO_OPAQUE,&rc,s,n,0);
   }while(i<31);
   SelectFont(dc,ofont);
   solver.paint(dc);
   EndPaint(Wnd,&ps);
  }return 0;
  
  case WM_PRINTCLIENT: {
  }break;
  
  case WM_QUERYOPEN: {
   TCHAR s[64];
   LoadString(ghInstance,1,s,elemof(s));
   SetWindowText(Wnd,s);
  }break;

  case WM_COMMAND:
  case WM_SYSCOMMAND: switch (wParam&0xFFF0) {
   case 0x10: SendMessage(Wnd,WM_CLOSE,0,0); break;
   case 0x20: tagplus(1); break;
   case 0x30: tagplus(-1); break;
   case 0x40: {
    Config.flags^=1;
    CheckMenuItem(GetMenu(Wnd),(UINT)wParam,Config.flags&1?MF_CHECKED:MF_UNCHECKED);
    tagplus(0);
   }break;
   case 0x50: {
    Config.flags^=2;
    CheckMenuItem(GetMenu(Wnd),(UINT)wParam,Config.flags&2?MF_CHECKED:MF_UNCHECKED);
   }break;
  }break;
  
  case WM_CLOSE: {
   SendMessage(Wnd,WM_ENDSESSION,1,0);		// speichern auslösen!
  }break;
  
  case WM_ENDSESSION: if (wParam) SaveConfig(); break;
  
  case WM_DESTROY: {
   DeleteFont(ghFont);
   PostQuitMessage(0);
  }break;
 }
  
 return DefWindowProc(Wnd,Msg,wParam,lParam);
}

/******************************
 * Hauptprogramm (lächerlich) *
 ******************************/
 
int _stdcall WinMainCRTStartup(void) {
 ghInstance=GetModuleHandle(NULL);

 LoadString(0,0,StdMBoxTitle,elemof(StdMBoxTitle));	// Kalenderpuzzle-Löser
 
 WNDCLASSEX wc;
 InitStruct(&wc,sizeof(wc));
 wc.style=CS_HREDRAW|CS_VREDRAW;
 wc.lpfnWndProc=MainWndProc;
 wc.hInstance=ghInstance;
 wc.hCursor=LoadCursor(0,IDC_ARROW);
 wc.hIcon=LoadIcon(ghInstance,MAKEINTRESOURCE(100));
 wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 wc.lpszMenuName=MAKEINTRESOURCE(100);
 wc.lpszClassName=T("kp");

 RegisterClassEx(&wc);
 InitCommonControls();		// wichtig für Teletubbieoptik!

 ghMainWnd=CreateWindowEx(WS_EX_ACCEPTFILES|WS_EX_OVERLAPPEDWINDOW,
   T("kp"),NULL,WS_OVERLAPPEDWINDOW,
   CW_USEDEFAULT,0,
   CW_USEDEFAULT,0,
   0,0,ghInstance,GetCommandLine());
 ShowWindow(ghMainWnd,SW_SHOWDEFAULT);

 MSG Msg;
 while (GetMessage(&Msg,0,0,0)) {
  if (IsDialogMessage(ghMainWnd,&Msg)) continue;
  TranslateMessage(&Msg);
  DispatchMessage(&Msg);
 }
 ExitProcess((UINT)Msg.wParam);
}
Vorgefundene Kodierung: UTF-80