Example #1
0
Matrix circshift(const Matrix& a, const Matrix& p)
{
	Matrix out = ZMatrix(a.size1(), a.size2());
	Matrix sizeA(1, 2);
	const int numDimsA = 2;
	sizeA(0, 0) = a.size1();
	sizeA(0, 1) = a.size2();
	int_vector idx0, idx1;
	for(int i = 0; i < a.size1(); ++i)
	{
		idx0.push_back((i + a.size1() - (int)p(0, 0)) % a.size1());
	}
	for(int i = 0; i < a.size2(); ++i)
	{
		idx1.push_back((i + a.size2() - (int)p(0, 1)) % a.size2());
	}
	for(int i = 0; i < a.size1(); ++i)
	{
		for(int j = 0; j < a.size2(); ++j)
		{
			out(i, j) = a(idx0[i], idx1[j]);
		}
	}
	return out;
}
Example #2
0
//---------------------------------------------------------------------------
void parseScore(BYTE *data, int len)
{
	int i, n, Nname;
	WCHAR *w, **nameA=0;
	BYTE b;
	WORD d;
	TscoreTab *t;
	TScore *r;
	BYTE *p=data;

	if(!strncmp((char*)data, "Color Sudoku score 2", 20)){
		try
		{
			p+=20;
			//names
			Nname= *(WORD*)p;
			p+=2;
			nameA= new WCHAR*[Nname];
			w=(WCHAR*)p;
			for(i=0; i<Nname; i++){
				nameA[i]=w;
				w=wcschr(w, 0)+1;
			}
			p=(BYTE*)w;
			//score tables
			for(; p<data+len;){
				b=p[2];
				t=getScoreTab(p[0], p[1], (BYTE)(b&1), (BYTE)((b>>1)&1), (BYTE)((b>>2)&1),
					(BYTE)((b>>3)&1), (BYTE)((b>>4)&1), (BYTE)(b&0xe0));
				memset(t->score, 0, sizeof(t->score));
				p+=3;
				n=*p++;
				for(i=0; i<n; i++){
					r=&t->score[i];
					if(r<endA(t->score)){
						//name
						r->name[0]=0;
						d= *(WORD*)p;
						if(d<Nname) wcsncpy(r->name, nameA[d], sizeA(r->name));
						r->name[sizeA(r->name)-1]=0;
						//time and date
						r->playtime= *(WORD*)(p+2);
						memcpy(&r->date, p+4, 6);
						//if(r->date.wYear<1990 || r->date.wYear>3000) r->playtime=0;
					}
					p+=10;
				}
			}
		} catch(...)
		{
			msg("Score table is damaged");
		}
		delete[] nameA;
	}
	else if(len%(Dscore*sizeof(TScore))==0){
LRESULT CALLBACK AboutProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM)
{
	char buf[48];
	DWORD d;

	switch(message){
		case WM_INITDIALOG:
			setDlgTexts(hWnd, 11);
			d=getVer();
			sprintf(buf, "%d.%d", HIWORD(d), LOWORD(d));
			SetDlgItemTextA(hWnd, 101, buf);
			return TRUE;

		case WM_COMMAND:
			switch(wParam){
				case IDOK:
				case IDCANCEL:
					EndDialog(hWnd, wParam);
					return TRUE;
				case 123:
					GetDlgItemTextA(hWnd, wParam, buf, sizeA(buf)-13);
					if(!_tcscmp(lang, _T("English"))) strcat(buf, "/indexEN.html");
					ShellExecuteA(0, 0, buf, 0, 0, SW_SHOWNORMAL);
					break;
			}
			break;
	}
	return FALSE;
}
void initGameTypeCombo(HWND hWnd)
{
	int i, j, sel=0;

	for(i=0; i<sizeA(gameTypeComboOrder); i++){
		j=gameTypeComboOrder[i];
		if(j==gameType) sel=i;
		SendDlgItemMessageA(hWnd, 170, CB_ADDSTRING, 0, (LPARAM)gameTypeA[j].name);
	}
	SendDlgItemMessage(hWnd, 170, CB_SETCURSEL, sel, 0);
}
//------------------------------------------------------------------
void checkMenus()
{
	symbol= symbol0;
	if(killer) symbol=0;
	HMENU m=GetMenu(hWin);
	CheckMenuRadioItem(m, ID_SIZE+4, ID_SIZE+Msize, ID_SIZE+size, MF_BYCOMMAND);
	CheckMenuRadioItem(m, 350, 352, 350+symbol0, MF_BYCOMMAND);
	CheckMenuRadioItem(m, ID_MULTI, ID_MULTI+sizeA(gameTypeA)-1, ID_MULTI+gameType, MF_BYCOMMAND);

	for(Toption *to=optionA; to<endA(optionA); to++){
		CheckMenuItem(m, to->menu, *to->value ? MF_BYCOMMAND|MF_CHECKED : MF_BYCOMMAND|MF_UNCHECKED);
	}
	//CheckMenuItem(m,ID_SHOWERR,showErr ? MF_BYCOMMAND|MF_CHECKED:MF_BYCOMMAND|MF_UNCHECKED);
	HMENU m1=GetSubMenu(m, 2);
	EnableMenuItem(m1, GetMenuItemCount(m1)-2, killer ? MF_BYPOSITION|MF_GRAYED : MF_BYPOSITION|MF_ENABLED);
}
void numButtons()
{
	int i;

	for(i=0; i<toolSize; i++){
		SendMessage(toolbar, TB_DELETEBUTTON, sizeA(tbb), 0);
	}
	toolSize=size;
	static TBBUTTON but[Msymbol];
	for(i=0; i<size; i++){
		TBBUTTON *b= but+i;
		b->fsState=TBSTATE_ENABLED;
		b->fsStyle=TBSTYLE_CHECK;
		static int O[]={0, 9, 35};
		b->iBitmap=i+toolNumIndex+O[symbol];
		b->idCommand=ID_SYMBOL+i;
	}
	SendMessage(toolbar, TB_ADDBUTTONS, size, (LPARAM)but);
	SendMessage(toolbar, TB_CHECKBUTTON, ID_SYMBOL+selectedNum, MAKELONG(TRUE, 0));
}
//------------------------------------------------------------------
LRESULT CALLBACK WndMainProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int i, notif;
	Tsquare *t;

	switch(message){
		case WM_PAINT:
		{
			static PAINTSTRUCT ps;
			BeginPaint(hWnd, &ps);
			paint(ps.hdc, &ps.rcPaint);
			EndPaint(hWnd, &ps);
		}
			break;
		case WM_LBUTTONDOWN:
			lbutton(lParam);
			break;
		case WM_RBUTTONDOWN:
			rbutton(lParam);
			break;
		case WM_LBUTTONUP:
			if(inserting){
				ReleaseCapture();
				inserting=false;
				insertGroup();
				resetSolution();
			}
			break;
		case WM_MOUSEMOVE:
			if(inserting){
				t= hitTest(lParam);
				if(t && t!=insSquares[insLen-1] && insLen<Nsymbol){
					insSquares[insLen++]=t;
				}
			}
#ifdef _DEBUGM
			mousemove(lParam);
#endif
			break;

		case WM_TIMER:
			if(!IsIconic(hWin)){
				playtime++;
				statusTime();
				checkShowErr(false);
			}
			break;
		case WM_KEYDOWN:
			key(wParam);
			break;
		case WM_GETMINMAXINFO:
		{
			LPMINMAXINFO lpmm = (LPMINMAXINFO)lParam;
			lpmm->ptMinTrackSize.x = 250;
			lpmm->ptMinTrackSize.y = 200+toolH;
			break;
		}
		case WM_SIZE:
			width=LOWORD(lParam);
			height=HIWORD(lParam);
			SendMessage(toolbar, TB_AUTOSIZE, 0, 0);
			SendMessage(statusbar, WM_SIZE, 0, 0);
			onMoved();
			invalidate();
			break;
		case WM_MOVE:
			onMoved();
			break;
		case WM_CLOSE:
			SendMessage(hWin, WM_COMMAND, ID_EXIT, 0);
			break;
		case WM_QUERYENDSESSION:
			writeini();
			return TRUE;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		case WM_COMMAND:
			notif=HIWORD(wParam);
			wParam=LOWORD(wParam);
			if(setLang(wParam)) break;
			if(wParam>=ID_SYMBOL && wParam<unsigned(ID_SYMBOL+size)){
				select(wParam-ID_SYMBOL);
				break;
			}
			if(wParam>=ID_SIZE+4 && wParam<=ID_SIZE+Msize){
				if(askNew()) break;
				size=wParam-ID_SIZE;
				newGameFormat();
				numButtons();
				break;
			}
			if(wParam>=ID_MULTI && wParam<ID_MULTI+sizeA(gameTypeA)-1){
				if(askNew()) break;
				gameType=wParam-ID_MULTI;
				newGameFormat();
				break;
			}

			switch(wParam){
				case ID_CLEAR:
					noScore=true;
					init(false);
					invalidate();
					break;
				case ID_CLEAR_ALL:
					noScore=true;
					initSquare(false);
					invalidate();
					break;
				case ID_EDITOR:
					if(!editor){
						if((undoPos==0 || done==Nsquare) && isGenerated()){
							initSquare(false);
						}
						editor=true;
						playtime=0;
						noScore=true;
						editorChanged();
					}
					break;
				case ID_EDITOR_END:
					if(editor){
						endEditor();
						editor=false;
						editorChanged();
					}
					break;
				case ID_SOLVE:
				case ID_SOLVE1:
					if(testTotal()) break;
					noScore=true;
					if(done<Nsquare){
						waitOn();
#ifdef _DEBUG
						DWORD time=getTickCount();
#endif
						Nsolution=0;
						curSolution=-1; //find all solutions (up to Msolution)
						undoAllPos=undoPos;
						if(wParam==ID_SOLVE1) resolve1(); else resolve();
						freeGroups();
#ifdef _DEBUG
						status(4, _T("%d ms"), getTickCount()-time);
#endif
						waitOff();
					}
					if(Nsolution>0){
						i=curSolution;
						curSolution++;
						if(curSolution>=Nsolution) curSolution=0;
						if(Nsolution>1){
							if(i<0){
								status(4, _T("%d %s"), Nsolution, lng(662, "solutions"));
							}
							else{
								status(4, _T("%d/%d"), curSolution+1, Nsolution);
							}
						}
						rdSolution();
					}
					else{ //easy solution (without recurse) or not solvable
						curSolution=0;
						status(4, _T(""));
					}
					checkErr();
					invalidate();
					break;
				case ID_CHEAT:
					noScore=true;
					if(errTime<0){
						waitOn();
						hint();
						waitOff();
					}
					checkShowErr(true);
					break;
				case ID_UNDO:
					undo();
					checkErr();
					break;
				case ID_REDO:
					redo();
					checkErr();
					break;
				case ID_UNDO_SYMBOL:
					undoSymbol();
					checkErr();
					break;
				case ID_REDO_SYMBOL:
					redoSymbol();
					checkErr();
					break;
				case ID_UNDO_ALL:
					undoAll();
					checkErr();
					break;
				case ID_REDO_ALL:
					while(redo());
					checkErr();
					break;
				case ID_DEL:
					select(-1);
					break;
				case ID_INS:
					select(-2);
					break;
				case ID_SIGN:
					select(-3);
					break;
				case ID_CONS:
					select(-4);
					break;
				case ID_EVEN:
					select(-5);
					break;
				case ID_EXIT:
					writeini();
					DestroyWindow(hWin);
					break;
				case ID_DIAGONAL:
					if(askNew()) break;
					diag=!diag;
					newGameFormat();
					break;
				case ID_SYMETRIC:
					if(askNew()) break;
					symetric=!symetric;
					newGameFormat();
					break;
				case ID_LEVEL:
					if(DialogBox(inst, MAKEINTRESOURCE(IDD_LEVEL), hWnd, (DLGPROC)LevelProc)){
						if(!editor) newGame();
					}
					break;
				case ID_SHOWERR:
					DialogBox(inst, MAKEINTRESOURCE(IDD_ERRTIME), hWnd, (DLGPROC)ShowErrProc);
					break;
				case ID_KILLER:
					if(askNew()) break;
					killer=!killer;
					newGameFormat();
					numButtons();
					break;
				case ID_GREATER:
					if(askNew()) break;
					greater=!greater;
					newGameFormat();
					break;
				case ID_CONSECUTIVE:
					if(askNew()) break;
					consecutive=!consecutive;
					newGameFormat();
					if(selectedNum==-4 && !consecutive) select(-1);
					break;
				case ID_ODDEVEN:
					if(askNew()) break;
					oddeven=!oddeven;
					newGameFormat();
					if(selectedNum==-5 && !oddeven) select(-1);
					break;
				case ID_DIGITS:
				case ID_LETTERS:
				case ID_COLORS:
					symbol0=wParam-350;
					checkMenus();
					invalidate();
					numButtons();
					break;
				case ID_NEWGAME:
					if(editor) SendMessage(hWnd, WM_COMMAND, ID_EDITOR_END, 0);
					else newGame();
					break;
				case ID_DELINI:
					delreg=true;
					break;
				case ID_DELHISCORE:
					if(MessageBox(hWnd,
						lng(799, "Do you really want to delete all hiscores ?"), title,
						MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES){
						for(TscoreTab *tab=score; tab;){
							TscoreTab *t1= tab->next;
							delete tab;
							tab=t1;
						}
						score=0;
						writeScore();
					}
					break;
				case ID_BEST_SCORES:
					DialogBox(inst, MAKEINTRESOURCE(IDD_HISCORE), hWnd, (DLGPROC)ScoreProc);
					break;
				case ID_COLORDLG:
					DialogBox(inst, MAKEINTRESOURCE(IDD_COLORS), hWin, (DLGPROC)ColorProc);
					break;
				case ID_ABOUT:
					DialogBox(inst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutProc);
					break;
				case ID_HELP_README:
				{
					TCHAR *buf=(TCHAR*)_alloca(2*MAX_PATH);
					getExeDir(buf, lng(13, "readme.txt"));
					if(ShellExecute(0, _T("open"), buf, 0, 0, SW_SHOWNORMAL)==(HINSTANCE)ERROR_FILE_NOT_FOUND){
						msglng(730, "Cannot open %s", buf);
					}
				}
					break;
				case ID_WRBMP:
					if(saveFileDlg(&bmpOfn, hWnd, 0)){
						wrBmp(bmpFn, bmpOfn.nFilterIndex);
					}
					break;
				case ID_SAVE:
					if(saveFileDlg(&gameOfn, hWnd, OFN_OVERWRITEPROMPT)){
						save(gameFn);
					}
					break;
				case ID_OPEN:
					if(openFileDlg(&gameOfn, hWnd, OFN_FILEMUSTEXIST|OFN_HIDEREADONLY)){
						open(gameFn);
						checkErr();
					}
					break;
				case ID_CLEAR_GRP:
					resetSolution();
					for(i=0; i<Ngroup; i++){
						delGroup(&group[i]);
					}
					invalidate();
					break;
				case ID_CLEAR_SGN:
				case ID_CLEAR_CONS:
					resetSolution();
					for(i=0; i<Nboard; i++){
						if(wParam==ID_CLEAR_SGN){
							putSign(0, &board[i], 0);
							putSign(0, &board[i], 1);
						}
						if(wParam==ID_CLEAR_CONS){
							putCons(false, &board[i], 0);
							putCons(false, &board[i], 1);
						}
					}
					invalidate();
					break;
				case ID_MARKS:
					noScore=true;
					showMarks();
					break;
				case ID_DELMARKS:
					delAllMarks();
					break;
				case ID_PDF:
					if(askNew()) break;
					DialogBox(inst, MAKEINTRESOURCE(IDD_PDF), hWnd, (DLGPROC)PdfProc);
					numButtons();
					break;
			}
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
//---------------------------------------------------------------------------
BOOL CALLBACK PdfProc(HWND hWnd, UINT msg, WPARAM wP, LPARAM)
{
	struct PageSize {
		int w, h;
		TCHAR *s;
	};
	static const PageSize P[]=
	{{595, 842, _T("A4")}, {421, 595, _T("A5")}, {842, 1190, _T("A3")}};
	static const int L[]={1, 2, 3, 4, 6, 9, 12};
	int i;
	HWND combo;
	Toption *to;
	TCHAR buf[4];

	switch(msg){
		case WM_INITDIALOG:
			setDlgTexts(hWnd, 26);
			SetDlgItemInt(hWnd, 160, pdfObject.count, FALSE);
			SetDlgItemInt(hWnd, 163, pdfObject.pageWidth, FALSE);
			SetDlgItemInt(hWnd, 164, pdfObject.pageHeight, FALSE);
			combo= GetDlgItem(hWnd, 162);
			for(i=0; i<sizeA(P); i++){
				const PageSize *p = &P[i];
				SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)p->s);
				if(pdfObject.pageWidth==p->w && pdfObject.pageHeight==p->h){
					SendMessage(combo, CB_SETCURSEL, i, 0);
				}
			}
			combo= GetDlgItem(hWnd, 161);
			for(i=0; i<sizeA(L); i++){
				_stprintf(buf, _T("%d"), L[i]);
				SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)buf);
			}
			initGameTypeCombo(hWnd);
			SetDlgItemInt(hWnd, 161, pdfObject.countPerPage, FALSE);
			SetDlgItemInt(hWnd, 168, pdfObject.border, FALSE);
			SetDlgItemInt(hWnd, 169, pdfObject.spacing, FALSE);
			CheckRadioButton(hWnd, 350, 352, 350+symbol0);
			for(to=optionA; to<endA(optionA); to++){
				CheckDlgButton(hWnd, to->dialog, *to->value ? BST_CHECKED : BST_UNCHECKED);
			}
			SetDlgItemInt(hWnd, 165, level, FALSE);
			SetDlgItemText(hWnd, 166, pdfObject.fn);
			return TRUE;

		case WM_COMMAND:
			wP=LOWORD(wP);
			if(wP==IDOK){
				pdfObject.count = 2 * GetDlgItemInt(hWnd, 160, 0, FALSE);
				//page properties
				pdfObject.pageWidth = GetDlgItemInt(hWnd, 163, 0, FALSE);
				pdfObject.pageHeight = GetDlgItemInt(hWnd, 164, 0, FALSE);
				pdfObject.countPerPage = GetDlgItemInt(hWnd, 161, 0, FALSE);
				pdfObject.border = GetDlgItemInt(hWnd, 168, 0, FALSE);
				pdfObject.spacing = GetDlgItemInt(hWnd, 169, 0, FALSE);
				//game options
				for(to=optionA; to<endA(optionA); to++){
					*to->value= IsDlgButtonChecked(hWnd, to->dialog);
				}
				level= GetDlgItemInt(hWnd, 165, 0, FALSE);
				symbol0= getRadioButton(hWnd, 350, 352);
				gameType=getGameType(hWnd);

				GetDlgItemText(hWnd, 166, pdfObject.fn, sizeA(pdfObject.fn));
				EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
				pdfObject.print(hWnd);
				EndDialog(hWnd, wP);
			}
			if(wP==IDCANCEL) EndDialog(hWnd, wP);
			if(wP==162){
				i=SendDlgItemMessage(hWnd, 162, CB_GETCURSEL, 0, 0);
				if(i>=0 && i<sizeA(P)){
					SetDlgItemInt(hWnd, 163, P[i].w, FALSE);
					SetDlgItemInt(hWnd, 164, P[i].h, FALSE);
				}
			}
			if(wP==167){
				if(saveFileDlg(&pdfOfn, hWnd, 0)){
					SetDlgItemText(hWnd, 166, pdfObject.fn);
				}
			}
			break;
	}
	return FALSE;
}
//------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int cmdShow)
{
	int i;
	HDC dc;
	MSG mesg;
	RECT rc;

	inst = hInstance;

	//DPIAware
	typedef BOOL(WINAPI *TGetProcAddress)();
	TGetProcAddress getProcAddress = (TGetProcAddress)GetProcAddress(GetModuleHandle(_T("user32")), "SetProcessDPIAware");
	if(getProcAddress) getProcAddress();

	memset(custom, 200, sizeof(custom));
	_tcscpy(pdfObject.fn, _T("sudoku.pdf"));
	pdfObject.pageWidth=595;
	pdfObject.pageHeight=842;
	pdfObject.count=6;
	pdfObject.countPerPage=6;
	pdfObject.border=40;
	pdfObject.spacing=20;
	readini();
	//load common controls
#if _WIN32_IE >= 0x0300
	INITCOMMONCONTROLSEX iccs;
	iccs.dwSize= sizeof(INITCOMMONCONTROLSEX);
	iccs.dwICC= ICC_BAR_CLASSES;
	InitCommonControlsEx(&iccs);
#else
	InitCommonControls();
#endif
	// create the main window
	WNDCLASS wc;
	ZeroMemory(&wc, sizeof(wc));
	wc.lpfnWndProc = WndMainProc;
	wc.hInstance = inst;
	wc.lpszClassName = CLASSNAME;
	wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU);
	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon         = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
	if(!RegisterClass(&wc)){
#ifdef UNICODE
		msg("This version cannot run on Windows 95/98/ME.");
#else
		msg("RegisterClass failed");
#endif
		return 2;
	}
	scrW= GetSystemMetrics(SM_CXSCREEN);
	scrH= GetSystemMetrics(SM_CYSCREEN);
	aminmax(mainLeft, 0, scrW-50);
	aminmax(mainTop, 0, scrH-50);
	hWin = CreateWindow(CLASSNAME, title,
		WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
		mainLeft, mainTop, mainW, mainH, 0, 0, inst, 0);
	if(!hWin){
		msg("CreateWindow failed");
		return 3;
	}

	haccel= LoadAccelerators(inst, MAKEINTRESOURCE(IDR_ACCELERATOR));
	Naccel= CopyAcceleratorTable(haccel, accel, sizeA(accel));
	initLang();
	//create status bar
	statusbar= CreateStatusWindow(WS_CHILD, 0, hWin, 1);
	static int parts[]={100, 140, 210, 230, -1};
	dc=GetDC(hWin);
	for(i=0; i<sizeA(parts)-1; i++){
		parts[i]=parts[i]*GetDeviceCaps(dc, LOGPIXELSX)/96;
	}
	ReleaseDC(hWin, dc);
	SendMessage(statusbar, SB_SETPARTS, sizeA(parts), (LPARAM)parts);
	ShowWindow(statusbar, SW_SHOW);
	//create tool bar
	i=sizeA(tbb);
	for(TBBUTTON *u=tbb; u<endA(tbb); u++){
		if(u->fsStyle==TBSTYLE_SEP) i--;
	}
	toolbar = CreateToolbarEx(hWin,
		WS_CHILD|TBSTYLE_TOOLTIPS, 2, i,
		inst, IDB_TOOLBAR, tbb, sizeA(tbb),
		16, 16, 16, 15, sizeof(TBBUTTON));
	GetClientRect(toolbar, &rc);
	MapWindowPoints(toolbar, hWin, (POINT*)&rc, 2);
	toolH= rc.bottom;
	if(toolBarVisible) ShowWindow(toolbar, SW_SHOW);

	langChanged();
	ShowWindow(hWin, cmdShow);
	initSquare(false);

	UpdateWindow(hWin);
	toolBitmap();
	numButtons();

	while(GetMessage(&mesg, NULL, 0, 0)==TRUE){
		if(!TranslateAccelerator(hWin, haccel, &mesg)){
			TranslateMessage(&mesg);
			DispatchMessage(&mesg);
		}
	}
	if(delreg) deleteini(HKEY_CURRENT_USER);
	return 0;
}
	{1, ID_UNDO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0},
	{0, ID_REDO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0},
	{2, ID_REDO_ALL, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0},
	{5, ID_DEL, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0},
	{6, ID_INS, TBSTATE_ENABLED|TBSTATE_HIDDEN, TBSTYLE_BUTTON, {0}, 0},
	{7, ID_SIGN, TBSTATE_ENABLED|TBSTATE_HIDDEN, TBSTYLE_BUTTON, {0}, 0},
	{8, ID_CONS, TBSTATE_ENABLED|TBSTATE_HIDDEN, TBSTYLE_BUTTON, {0}, 0},
	{9, ID_EVEN, TBSTATE_ENABLED|TBSTATE_HIDDEN, TBSTYLE_BUTTON, {0}, 0},
	{0, 0, 0, TBSTYLE_SEP, {0}, 0},
};

OPENFILENAME gameOfn={
	sizeof(OPENFILENAME), 0, 0,
	_T("Sudoku (*.sud)\0*.sud\0(*.*)\0*.*\0"),
	0, 0, 1,
	gameFn, sizeA(gameFn),
	0, 0, 0, 0, 0, 0, 0, _T("SUD"), 0, 0, 0
};
OPENFILENAME bmpOfn={
	sizeof(OPENFILENAME), 0, 0,
#ifdef USE_PNG
	_T("Portable Network Graphics (*.png)\0*.png\0Bitmap (*.bmp)\0*.bmp\0"),
#else
	_T("Bitmap (*.bmp)\0*.bmp\0"),
#endif
	0, 0, 1,
	bmpFn, sizeA(bmpFn),
	0, 0, 0, 0, 0, 0, 0,
#ifdef USE_PNG
	_T("PNG"),
#else