/* 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);
}
Detected encoding: UTF-8 | 0
|