0001:
0002:
0003:
0004:
0005:
0006: #include <windows.h>
0007: #include <stdio.h>
0008: #include <math.h>
0009: #include <dir.h>
0010: #include <sys/stat.h>
0011: #include <io.h>
0012:
0013: typedef int GrInt;
0014: #include "ct_puzzle_common.c"
0015: #include "icontools.c"
0016: HICON IconGross = NULL, IconKlein = NULL;
0017:
0018: #define ThisClassName "arnold's ct-Puzzle-select"
0019: #define ThisTitleBar "Arnold's c't-Puzzle-Ergebnis-Viewing-Tool(s)"
0020:
0021: #define ERGEBNIS "ct_puzzle_erg.bin"
0022: #define DEFAULT_VIEWING_CMD "neut2slp -d"
0023: #define BERECHNUNGSPROGRAMM "ct_puzzle_erg"
0024:
0025: #define MN_START_SUCHE 200
0026: #define MN_DIMETSCALE 201
0027: #define MN_DIMET_S1 202
0028: #define MN_DIMET_S2 203
0029: #define MN_DIMET_S3 204
0030: #define MN_PARTS 205
0031: #define MN_MIRROR_1 206
0032: #define MN_MIRROR_2 207
0033: #define MN_MIRROR_9 208
0034: #define MN_FILTER 209
0035: #define MN_FILTER_CLEAR 210
0036: #define MN_FILTER_A_B 211
0037: #define MN_FILTER_A_C 212
0038: #define MN_FILTER_A_D 213
0039: #define MN_INFO 290
0040: HMENU DimetrieMenu = NULL, SpiegelMenu = NULL;
0041: #define CMD_FILTER 300
0042: #define CMD_FB 316
0043: #define CMD_FILTERINFO 301
0044: #define CMD_VWR_NAME 302
0045: #define CMD_VWR_STRT 303
0046: #define CMD_SOL_EDIT 304
0047: #define CMD_SOL_NEXT 305
0048: #define CMD_SOL_PREV 306
0049: #define CMD_ALTSUCHE 307
0050: #define CMD_SUCHE 308
0051: #define CMD_SCROLL 309
0052: #define CMD_ADDITEM 310
0053: #define CMD_ADDITEMSTRT 311
0054: #define CMD_SEARCHEND 312
0055: #define CMD_STATISTIK 313
0056: #define CMD_SEARCHPRED 314
0057: #define CMD_SEARCHSUCC 315
0058:
0059: #define PictWidth1 60
0060: HINSTANCE hThisInstance;
0061: HWND hwndApplication;
0062: int cxChar, cyChar, cxScreen, cyScreen;
0063: int Grenze1, Grenze2, BH1, EH1, MH1, EW1, EWB1, EHD, SBx, PMx, LSx, SSx, SSy, SSl, SSp = 0, TXy;
0064: int DI1_cx, DI1_cy, DI2_cx, DI2_cy, DI_scale = 1;
0065: int Filter_an = 0, SucheAlle = 0, BitteSuchen = 0;
0066: RECT Bereich1, Bereich2, Bereich3;
0067: HWND Filter, FilterInfo;
0068: HWND Vorgaben[BAUSTEINZAHL][3];
0069: HWND Viewer_Start, Viewer_Cmd, Viewer_Title;
0070: HWND Loesung_Title, Loesung_Nr, Loesung_plus, Loesung_minus;
0071: HWND SucheAlt, SucheStart, SucheScroll, SucheStat, SuchePred, SucheSucc;
0072: HBRUSH HintergrundLeiste = NULL;
0073: int Vorgabenwerte[BAUSTEINZAHL][3][4];
0074: int VorgabeAktivBS = -1, VorgabeAktivSp = -1;
0075: int MarkierterBS = -1;
0076:
0077: int SearchThread_halt = 0, SearchThread_halted = 1, SearchThread_start = 0, SearchThread_started = 0,
0078: SearchThread_Suspend = 0;
0079: HANDLE SearchThread = NULL;
0080: DWORD SearchThreadId;
0081: FILE *SearchThreadDat = NULL;
0082:
0083: unsigned long Loesung = 0; int Loesungslage = -1;
0084: int Mirror1 = 0, Mirror2 = 0, Mirror9 = 0;
0085: FILE *Loesungsdatei = NULL;
0086: unsigned short Loesungssatz[12];
0087: int LoesungssatzGueltig = 0;
0088:
0089: int SuchErgebnisse = 0;
0090: int SuchBlockSeite = 0;
0091: int ChoosenResult = -1;
0092: int ScrollOffset = 0;
0093: #define SuchBlockSize 1000
0094: struct SUCHBLOCK {
0095: int in_diesem_block;
0096: struct SUCHBLOCK *next, *prev;
0097: unsigned long Ergebnis[SuchBlockSize];
0098: } *StartSuchBlock = NULL, *AktiverSuchBlock = NULL, *LetzterSuchBlock = NULL;
0099:
0100: char *ErgebnisString(int EintragNummer)
0101: { int block, index;
0102: static char ErgString[40];
0103: block = EintragNummer / SuchBlockSize;
0104: index = EintragNummer % SuchBlockSize;
0105: ErgString[0] = '\0';
0106: if (StartSuchBlock == NULL) return ErgString;
0107: if (block == 0) {
0108: AktiverSuchBlock = StartSuchBlock; SuchBlockSeite = 0;
0109: } else
0110: if (block != SuchBlockSeite) {
0111: if (block > SuchBlockSeite) {
0112: while ((block != SuchBlockSeite) && (AktiverSuchBlock->next != NULL)) {
0113: AktiverSuchBlock = AktiverSuchBlock->next; SuchBlockSeite++;
0114: }
0115: } else {
0116: while ((block != SuchBlockSeite) && (AktiverSuchBlock->prev != NULL)) {
0117: AktiverSuchBlock = AktiverSuchBlock->prev; SuchBlockSeite--;
0118: }
0119: }
0120: }
0121: if (AktiverSuchBlock->in_diesem_block > index) {
0122: if ((AktiverSuchBlock->Ergebnis[index] >> 28) & 4)
0123: sprintf(ErgString, "%lu", AktiverSuchBlock->Ergebnis[index] & 0x0fffffffL);
0124: else
0125: sprintf(ErgString, "%lu%c", AktiverSuchBlock->Ergebnis[index] & 0x0fffffffL,
0126: 'a' + (((AktiverSuchBlock->Ergebnis[index]) >> 28) & 3));
0127: }
0128: return ErgString;
0129: }
0130:
0131: void PredSuccEnable(void)
0132: { EnableWindow(SuchePred, SuchErgebnisse ? TRUE : FALSE);
0133: EnableWindow(SucheSucc, SuchErgebnisse ? TRUE : FALSE);
0134: }
0135:
0136: void ClearErgebnis(void)
0137: { struct SUCHBLOCK *sb;
0138: SuchErgebnisse = SuchBlockSeite = SSp = 0;
0139: PredSuccEnable();
0140: AktiverSuchBlock = LetzterSuchBlock = StartSuchBlock;
0141: for (sb = StartSuchBlock; sb != NULL; sb = sb->next) sb->in_diesem_block = 0;
0142: ChoosenResult = -1;
0143: SetWindowText(SucheStat, "");
0144: }
0145:
0146: void AddErgebnis(unsigned long Nummer, int Lage)
0147: { unsigned long Schreibwert;
0148: struct SUCHBLOCK *Satz, *neu;
0149: char Zwischenstatistik[50];
0150: Schreibwert = Nummer | (Lage << 28);
0151: if (StartSuchBlock == NULL) {
0152: if((Satz = malloc(sizeof(struct SUCHBLOCK))) == NULL) return;
0153: Satz->next = NULL; Satz->prev = NULL; Satz->in_diesem_block = 0;
0154: StartSuchBlock = Satz;
0155: AktiverSuchBlock = Satz;
0156: LetzterSuchBlock = Satz;
0157: SuchBlockSeite = 0;
0158: }
0159: Satz = LetzterSuchBlock;
0160: while (Satz->in_diesem_block >= SuchBlockSize) {
0161: if (Satz->next == NULL) {
0162: if ((neu = malloc(sizeof(struct SUCHBLOCK))) == NULL) return;
0163: neu->prev = Satz; neu->next = NULL; neu->in_diesem_block = 0;
0164: LetzterSuchBlock = neu;
0165: Satz->next = neu;
0166: Satz = neu;
0167: } else Satz = Satz->next;
0168: }
0169: Satz->Ergebnis[Satz->in_diesem_block] = Schreibwert;
0170: (Satz->in_diesem_block)++;
0171: SuchErgebnisse++;
0172: PredSuccEnable();
0173: sprintf(Zwischenstatistik, "%u/%lu", SuchErgebnisse, Nummer & 0x0fffffffL);
0174: SetWindowText(SucheStat, Zwischenstatistik);
0175: }
0176:
0177: void StartLoesungsBerechnung(int start_von_winmain)
0178: { int ok;
0179: STARTUPINFO si;
0180: static PROCESS_INFORMATION pi;
0181: static calculation_started = 0;
0182: DWORD ec;
0183: if (!start_von_winmain) {
0184: if (!access(ERGEBNIS, 4)) {
0185: if (MessageBox(hwndApplication,
0186: "Sie wollen die Lösungstabelle neu berechnen lassen, obwohl die Datei \""
0187: ERGEBNIS "\" bereits vorhanden ist?\n"
0188: "Da diese Berechnung einige Stunden dauern kann (gemessen auf meinem Testrechner),"
0189: " überlegen Sie es sich gut, ob sie dies jetzt tun wollen, denn Sie sollten den"
0190: " Berechnungslauf nicht vorzeitig abbrechen.\n"
0191: "\nWollen Sie nun die Lösungstabelle neu berechnen?",
0192: "c't-Puzzle-Lösungstabelle berechnen", MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON2) == IDCANCEL)
0193: return;
0194: }
0195: }
0196: do {
0197: ok = 1;
0198:
0199: if (!SearchThread_halted || (SearchThreadDat != NULL)) {
0200: if (MessageBox(hwndApplication, "Um die Lösungsssuche starten zu können,"
0201: " muß die Filtersuche erst abgeschlossen sein!",
0202: "Lösungssuche starten ...", MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDCANCEL) return;
0203: ok = 0;
0204: }
0205:
0206: if (calculation_started) {
0207: if (GetExitCodeProcess(pi.hProcess, &ec)) {
0208: if (ec != STILL_ACTIVE) calculation_started = 0;
0209: }
0210: }
0211: if (calculation_started) {
0212: if (MessageBox(hwndApplication, "Es wurde bereits eine Lösungssuche gestartet und diese ist noch"
0213: "nicht beendet.\n", "Lösungssuche starten ...",
0214: MB_ICONEXCLAMATION | MB_RETRYCANCEL | MB_DEFBUTTON2) == IDCANCEL) return;
0215: ok = 0;
0216: }
0217: } while (!ok);
0218: if (Loesungsdatei != NULL) fclose(Loesungsdatei);
0219: memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO);
0220: if (CreateProcess(NULL, BERECHNUNGSPROGRAMM, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
0221: NULL, NULL, &si, &pi)) {
0222: calculation_started = 1;
0223: MessageBox(hwndApplication, "Die Berechnung der Lösungstabelle wurde gestartet. "
0224: "Dies kann einige Zeit dauern, bitte haben Sie deshalb jetzt etwas Geduld:\n"
0225: "Auf meinem Testrechner benötigte dieser Rechenlauf\n"
0226: "\n ca. 3\xbd Stunden Rechenzeit.\n\n[in Worten: sieben mal dreißig Minuten]",
0227: "Berechnung gestartet", MB_ICONINFORMATION | MB_OK | MB_SYSTEMMODAL);
0228: } else {
0229: MessageBox(hwndApplication, "Das Berechnungsprogramm \"" BERECHNUNGSPROGRAMM "\" konnte nicht gestartet"
0230: " werden!", "Fehler beim Starten der Lösungssuche", MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
0231: }
0232: }
0233:
0234: int SuchtGerade(void)
0235: { char Z[20];
0236: GetWindowText(SucheStart, Z, 20);
0237: Z[19] = '\0';
0238: if (!strcmp(Z, "Suche ...")) return 1;
0239: return 0;
0240: }
0241:
0242: void AdjustScrollbarSize(void)
0243: { SCROLLINFO si;
0244: si.cbSize = sizeof(si);
0245: si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
0246: si.nPos = ScrollOffset;
0247: si.nPage = SSl; si.nMin = 0; si.nMax = SuchErgebnisse - 1;
0248: SetScrollInfo(SucheScroll, SB_CTL, &si, TRUE);
0249: }
0250:
0251: int BausteinNummer(unsigned short InsertID)
0252: { return(((InsertID >> 12) & 15) - 1); }
0253:
0254: MATRIX Orientierung(unsigned short InsertID)
0255: { MATRIX erg;
0256: int xdir, ydir;
0257: memset(&erg, 0, sizeof(MATRIX));
0258:
0259: xdir = (InsertID >> 10) & 3;
0260: erg.MATRIX[xdir] = ((InsertID >> 9) & 1) ? -1 : 1;
0261:
0262: ydir = (xdir + 1 + ((InsertID >> 8) & 1)) % 3 + 3;
0263: erg.MATRIX[ydir] = ((InsertID >> 7) & 1) ? -1 : 1;
0264:
0265: erg.MATRIX[8] = erg.MATRIX[0] * erg.MATRIX[4] - erg.MATRIX[1] * erg.MATRIX[3];
0266: erg.MATRIX[6] = erg.MATRIX[1] * erg.MATRIX[5] - erg.MATRIX[2] * erg.MATRIX[4];
0267: erg.MATRIX[7] = erg.MATRIX[2] * erg.MATRIX[3] - erg.MATRIX[0] * erg.MATRIX[5];
0268:
0269: erg.MATRIX[ 9] = (InsertID >> 4) & 7;
0270: erg.MATRIX[10] = (InsertID >> 2) & 3;
0271: erg.MATRIX[11] = InsertID & 3;
0272:
0273: return erg;
0274: }
0275:
0276: #include "ct_puzzle_gdata.c"
0277:
0278:
0279: void ViewerStartLoesung(void)
0280: { int ct, bs, a, i;
0281: MATRIX m;
0282: STARTUPINFO si;
0283: PROCESS_INFORMATION pi;
0284: FILE *posdat;
0285: char PosDat[MAX_PATH];
0286: char Programm[2 * MAXPATH];
0287: if (!LoesungssatzGueltig) return;
0288: a = Loesungslage; if (a < 0) a = 0;
0289: mkdir("loesungen");
0290: sprintf(PosDat, "loesungen\\ct_puzzle_%.6lu%c.pos", Loesung, 'a' + a);
0291: if ((posdat = fopen(PosDat, "w")) == NULL) {
0292: char M[MAX_PATH + 70];
0293: sprintf(M, "Datei '%s' konnte nicht angelegt werden!", PosDat);
0294: MessageBox(NULL, M, "Datenübergabe fehlgeschlagen", MB_ICONEXCLAMATION | MB_OK);
0295: return;
0296: }
0297: for (ct = 0; ct < BAUSTEINZAHL; ct++) {
0298: bs = BausteinNummer(Loesungssatz[ct]);
0299: if ((bs >= 0) && (bs < BAUSTEINZAHL)) {
0300: if ((bs == 0) && Mirror1) {
0301: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV1));
0302: } else
0303: if ((bs == 1) && Mirror2) {
0304: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV2));
0305: } else
0306: if ((bs == 8) && Mirror9) {
0307: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV9));
0308: } else
0309: m = MatMul(Hinlegen[a], Orientierung(Loesungssatz[ct]));
0310: fprintf(posdat, "%2d ", bs + 1);
0311: for (i = 0; i < 12; i++) fprintf(posdat, " %2d", m.MATRIX[i]);
0312: fprintf(posdat, "\n");
0313: }
0314: }
0315: fclose(posdat);
0316: GetWindowText(Viewer_Cmd, Programm, MAX_PATH);
0317: Programm[MAX_PATH - 1] = '\0';
0318: strcat(Programm, " ");
0319: strcat(Programm, PosDat);
0320:
0321: memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO);
0322: CreateProcess(NULL, Programm, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
0323: NULL, NULL, &si, &pi);
0324: }
0325:
0326: void CheckCheckbox(HWND hwnd, int set_it)
0327: { SendMessage(hwnd, BM_SETCHECK, set_it ? BST_CHECKED : BST_UNCHECKED, 0L); }
0328:
0329: void SetSwitches(void)
0330: { int b, i;
0331: CheckCheckbox(Filter, Filter_an);
0332: for (b = 0; b < BAUSTEINZAHL; b++) for (i = 0; i < 3; i++)
0333: EnableWindow(Vorgaben[b][i], Filter_an ? TRUE : FALSE);
0334: EnableWindow(SucheAlt, Filter_an ? TRUE : FALSE);
0335: EnableWindow(SucheStart, Filter_an ? TRUE : FALSE);
0336: EnableWindow(SucheScroll, Filter_an ? TRUE : FALSE);
0337: CheckCheckbox(SucheAlt, SucheAlle);
0338: }
0339:
0340: void CreateSubwindows(HWND hwnd)
0341: { int b, i;
0342:
0343: Filter = CreateWindow("button", "Lösungen filtern",
0344: WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_BORDER,
0345: 0, 0, 0, 0, hwnd, (HMENU) CMD_FILTER, hThisInstance, NULL);
0346: for (b = 0; b < BAUSTEINZAHL; b++) for (i = 0; i < 3; i++) {
0347: Vorgaben[b][i] = CreateWindow("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,
0348: 0, 0, 0, 0, hwnd, (HMENU) (CMD_FB + 3 * b + i), hThisInstance, NULL);
0349: Vorgabenwerte[b][i][3] = 0;
0350: }
0351: FilterInfo = CreateWindow("static", "",
0352: WS_CHILD | WS_VISIBLE | SS_LEFT,
0353: 0, 0, 0, 0, hwnd, (HMENU) CMD_FILTERINFO, hThisInstance, NULL);
0354:
0355: SucheAlt = CreateWindow("button", "mit Rotationen",
0356: WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_BORDER,
0357: 0, 0, 0, 0, hwnd, (HMENU) CMD_ALTSUCHE, hThisInstance, NULL);
0358: SucheStart = CreateWindow("button", BitteSuchen ? "Suchen!" : "Suchen",
0359: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0360: 0, 0, 0, 0, hwnd, (HMENU) CMD_SUCHE, hThisInstance, NULL);
0361: SucheScroll = CreateWindow("scrollbar", NULL,
0362: WS_CHILD | WS_VISIBLE | SBS_VERT,
0363: 0, 0, 0, 0, hwnd, (HMENU) CMD_SCROLL, hThisInstance, NULL);
0364: SucheStat = CreateWindow("static", "",
0365: WS_CHILD | WS_VISIBLE | SS_CENTER,
0366: 0, 0, 0, 0, hwnd, (HMENU) CMD_STATISTIK, hThisInstance, NULL);
0367: SucheSucc = CreateWindow("button", "+",
0368: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0369: 0, 0, 0, 0, hwnd, (HMENU) CMD_SEARCHSUCC, hThisInstance, NULL);
0370: SuchePred = CreateWindow("button", "-",
0371: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0372: 0, 0, 0, 0, hwnd, (HMENU) CMD_SEARCHPRED, hThisInstance, NULL);
0373:
0374: Viewer_Title = CreateWindow("static", "3D-Viewer:",
0375: WS_CHILD | WS_VISIBLE | SS_LEFT,
0376: 0, 0, 0, 0, hwnd, (HMENU) 0, hThisInstance, NULL);
0377: Viewer_Cmd = CreateWindow("edit", DEFAULT_VIEWING_CMD,
0378: WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
0379: 0, 0, 0, 0, hwnd, (HMENU) CMD_VWR_NAME, hThisInstance, NULL);
0380: Viewer_Start = CreateWindow("button", "START",
0381: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0382: 0, 0, 0, 0, hwnd, (HMENU) CMD_VWR_STRT, hThisInstance, NULL);
0383: Loesung_Title = CreateWindow("static", "Lösung Nr.:",
0384: WS_CHILD | WS_VISIBLE | SS_LEFT | WS_BORDER,
0385: 0, 0, 0, 0, hwnd, (HMENU) 0, hThisInstance, NULL);
0386: Loesung_Nr = CreateWindow("edit", "",
0387: WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_LOWERCASE,
0388: 0, 0, 0, 0, hwnd, (HMENU) CMD_SOL_EDIT, hThisInstance, NULL);
0389: Loesung_plus = CreateWindow("button", "+",
0390: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0391: 0, 0, 0, 0, hwnd, (HMENU) CMD_SOL_NEXT, hThisInstance, NULL);
0392: Loesung_minus = CreateWindow("button", "-",
0393: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0394: 0, 0, 0, 0, hwnd, (HMENU) CMD_SOL_PREV, hThisInstance, NULL);
0395: SetSwitches();
0396: }
0397:
0398: void CheckSolutionNumber(int aktion)
0399: { char Nummer[22], NummerNeu[22];
0400: int md, p, q, nr, alternative; char c;
0401: struct stat sb;
0402: DWORD sel_strt, sel_end;
0403: GetWindowText(Loesung_Nr, Nummer, 22); Nummer[21] = '\0';
0404: SendMessage(Loesung_Nr, EM_GETSEL, (WPARAM) (LPDWORD) &sel_strt, (LPARAM) (LPDWORD) &sel_end);
0405: nr = 0; c = ' ';
0406: md = 0; NummerNeu[0] = '\0';
0407: for (p = q = 0; Nummer[p]; p++) {
0408: switch (md) {
0409: case 0:
0410: if ((Nummer[p] >= '0') && (Nummer[p] <= '9')) {
0411: NummerNeu[q] = Nummer[p];
0412: NummerNeu[++q] = '\0';
0413: } else if (q) {
0414: switch (Nummer[p]) {
0415: case 'a': case 'A': NummerNeu[q++] = 'a'; md = 1; break;
0416: case 'b': case 'B': NummerNeu[q++] = 'b'; md = 1; break;
0417: case 'c': case 'C': NummerNeu[q++] = 'c'; md = 1; break;
0418: case 'd': case 'D': NummerNeu[q++] = 'd'; md = 1; break;
0419: }
0420: NummerNeu[q] = '\0';
0421: } else {
0422: if (sel_strt) sel_strt--;
0423: if (sel_end) sel_end--;
0424: }
0425: break;
0426: }
0427: }
0428: NummerNeu[20] = '\0';
0429: if (sel_strt > strlen(NummerNeu)) sel_strt = strlen(NummerNeu);
0430: if (sel_end > strlen(NummerNeu)) sel_end = strlen(NummerNeu);
0431: sscanf(NummerNeu, "%u%c", &nr, &c);
0432: switch (c) {
0433: case 'a': case 'A': alternative = 0; break;
0434: case 'b': case 'B': alternative = 1; break;
0435: case 'c': case 'C': alternative = 2; break;
0436: case 'd': case 'D': alternative = 3; break;
0437: default: alternative = -1;
0438: }
0439: if (!aktion) {
0440: if (!stat(ERGEBNIS, &sb)) {
0441: if (nr > sb.st_size / 24L) nr = sb.st_size / 24L;
0442: if (alternative >= 0) sprintf(NummerNeu, "%u%c", nr, 'a' + alternative);
0443: else sprintf(NummerNeu, "%u", nr);
0444: ChoosenResult = -1;
0445: }
0446: if (strcmp(Nummer, NummerNeu)) {
0447: SetWindowText(Loesung_Nr, NummerNeu);
0448: SendMessage(Loesung_Nr, EM_SETSEL, (WPARAM) (INT) sel_strt, (LPARAM) (INT) sel_end);
0449: }
0450: }
0451: if (aktion) {
0452: if ((nr > 1) || (aktion > 0)) nr += aktion;
0453: if (!stat(ERGEBNIS, &sb)) {
0454: if (nr > sb.st_size / 24L) nr = sb.st_size / 24L;
0455: }
0456: if (nr == 0) nr = 1;
0457: if (alternative >= 0) sprintf(Nummer, "%c", 'a' + alternative); else Nummer[0] = '\0';
0458: sprintf(NummerNeu, "%u%s", nr, Nummer);
0459: NummerNeu[20] = '\0';
0460: SetWindowText(Loesung_Nr, NummerNeu);
0461: ChoosenResult = -1;
0462: }
0463: }
0464:
0465: void SelectSolutionNumber(HWND hwnd)
0466: { char Nummer[22];
0467: int nr, alternative; char c;
0468: GetWindowText(Loesung_Nr, Nummer, 22); Nummer[21] = '\0';
0469: nr = 0; c = ' ';
0470: sscanf(Nummer, "%u%c", &nr, &c);
0471: switch (c) {
0472: case 'a': case 'A': alternative = 0; break;
0473: case 'b': case 'B': alternative = 1; break;
0474: case 'c': case 'C': alternative = 2; break;
0475: case 'd': case 'D': alternative = 3; break;
0476: default: alternative = -1;
0477: }
0478: if (nr > 0) {
0479: Loesung = nr, Loesungslage = alternative;
0480: if (Loesungsdatei == NULL) {
0481: if ((Loesungsdatei = fopen(ERGEBNIS, "rb")) == NULL) {
0482: LoesungssatzGueltig = 0; return;
0483: }
0484: }
0485: fseek(Loesungsdatei, 24L * (Loesung - 1), SEEK_SET);
0486: fread(Loesungssatz, 24, 1, Loesungsdatei);
0487: LoesungssatzGueltig = 1;
0488: InvalidateRect(hwnd, &Bereich3, TRUE);
0489: } else
0490: if (LoesungssatzGueltig) {
0491: LoesungssatzGueltig = 0;
0492: InvalidateRect(hwnd, &Bereich3, TRUE);
0493: }
0494: }
0495:
0496: void SetDimetScale(int scale)
0497: { DI_scale = scale;
0498: CheckMenuItem(DimetrieMenu, MN_DIMET_S1, MF_BYCOMMAND | ((DI_scale == 1) ? MF_CHECKED : MF_UNCHECKED));
0499: CheckMenuItem(DimetrieMenu, MN_DIMET_S2, MF_BYCOMMAND | ((DI_scale == 2) ? MF_CHECKED : MF_UNCHECKED));
0500: CheckMenuItem(DimetrieMenu, MN_DIMET_S3, MF_BYCOMMAND | ((DI_scale == 3) ? MF_CHECKED : MF_UNCHECKED));
0501: DI1_cx = (cxScreen + Grenze2 + 93 * DI_scale) / 2;
0502: DI2_cx = (cxScreen + Grenze2 - 93 * DI_scale) / 2;
0503: DI1_cy = (1 * (cyScreen - 3 * BH1 - 1) - 114 * DI_scale) / 4 + BH1 + 1;
0504: DI2_cy = (3 * (cyScreen - 3 * BH1 - 1) - 114 * DI_scale) / 4 + BH1 + 1;
0505: }
0506:
0507: #pragma argsused
0508: void ChangeSize(HWND hwnd, LPARAM lParam)
0509: { int b, i;
0510: HDC hdc;
0511: TEXTMETRIC tm;
0512:
0513: hdc = GetDC(hwnd); GetTextMetrics(hdc, &tm); ReleaseDC(hwnd, hdc);
0514: TXy = tm.tmHeight + tm.tmExternalLeading + 2;
0515:
0516: EW1 = 6 * cxChar;
0517: Grenze1 = 3 * EW1 + PictWidth1;
0518: Grenze2 = Grenze1 + 15 * cxChar;
0519: Bereich1.top = 0; Bereich1.left = 0; Bereich1.bottom = cyScreen; Bereich1.right = Grenze1;
0520: Bereich2.top = 0; Bereich2.left = Grenze1; Bereich2.bottom = cyScreen; Bereich2.right = Grenze2;
0521: Bereich3.top = 0; Bereich3.left = Grenze2; Bereich3.bottom = cyScreen; Bereich3.right = cxScreen;
0522: BH1 = cyChar + 6;
0523: EHD = EH1 = (cyScreen - BH1 - 2) / (BAUSTEINZAHL + 2);
0524: MH1 = cyScreen - BH1 - BAUSTEINZAHL * EH1 - 1;
0525: EWB1 = BH1 + EH1 / 2 + 1;
0526: if (EH1 > cyChar + 6) { EH1 = cyChar + 6; }
0527:
0528: SSx = Grenze2 - 2 * cxChar;
0529: SSy = 2 * BH1 + 1;
0530: SSl = (cyScreen - SSy - 2 * BH1) / TXy;
0531:
0532: SBx = cxScreen - 7 * cxChar; if (SBx <= Grenze2) SBx = Grenze2 + 1;
0533: LSx = 9 * cxChar;
0534: PMx = cxScreen - 2 * cxChar; if (PMx <= Grenze2) { PMx = Grenze2 + 1; LSx = 0; }
0535: SetDimetScale(DI_scale);
0536:
0537: MoveWindow(Filter, 1, 1, Grenze1 - 1, BH1, TRUE);
0538: for (b = 0; b < BAUSTEINZAHL; b++)
0539: for (i = 0; i < 3; i++)
0540: MoveWindow(Vorgaben[b][i], Grenze1 - (3 - i) * EW1 + 1, EWB1 - EH1 / 2 + b * EHD , EW1 - 2, EH1 - 2, TRUE);
0541: MoveWindow(FilterInfo, 0, cyScreen - MH1, Grenze1, MH1, TRUE);
0542:
0543: MoveWindow(SucheAlt, Grenze1 + 1, 1, Grenze2 - Grenze1 - 1, BH1, TRUE);
0544: MoveWindow(SucheStart, Grenze1 + 1, BH1 + 1, Grenze2 - Grenze1 - 1, BH1, TRUE);
0545: MoveWindow(SucheStat, Grenze1 + 1, cyScreen - BH1, Grenze2 - Grenze1 - 1, BH1, TRUE);
0546: MoveWindow(SuchePred, Grenze1 + 1, cyScreen - 2 * BH1, (Grenze2 - Grenze1 - 1) / 2, BH1, TRUE);
0547: MoveWindow(SucheSucc, Grenze2 - (Grenze2 - Grenze1 - 1) / 2, cyScreen - 2 * BH1,
0548: (Grenze2 - Grenze1 - 1) / 2, BH1, TRUE);
0549: MoveWindow(SucheScroll, SSx, SSy, 2 * cxChar, cyScreen - SSy - 2 * BH1, TRUE);
0550: PredSuccEnable();
0551:
0552: MoveWindow(Loesung_plus, PMx, 1, cxScreen - PMx, BH1 / 2, TRUE);
0553: MoveWindow(Loesung_minus, PMx, BH1 / 2 + 1, cxScreen - PMx, BH1 / 2, TRUE);
0554: MoveWindow(Loesung_Title, Grenze2 + 1, 1, PMx - Grenze2 - 1, BH1, TRUE);
0555: MoveWindow(Loesung_Nr, PMx - LSx - 1, 2, LSx, BH1 - 2, TRUE);
0556: MoveWindow(Viewer_Title, Grenze2 + 1, cyScreen - 2 * BH1, SBx - Grenze2 - 1, BH1, TRUE);
0557: MoveWindow(Viewer_Cmd, Grenze2 + 1, cyScreen - BH1, SBx - Grenze2 - 1, BH1, TRUE);
0558: MoveWindow(Viewer_Start, SBx, cyScreen - 2 * BH1, cxScreen - SBx, 2 * BH1, TRUE);
0559: }
0560:
0561: void FilterLoeschen(void)
0562: { int bs, i;
0563: for (bs = 0; bs < BAUSTEINZAHL; bs++) for (i = 0; i < 3; i++) {
0564: SetWindowText(Vorgaben[bs][i], "");
0565: Vorgabenwerte[bs][i][3] = 0;
0566: }
0567: }
0568:
0569: void FilterWenden(int a)
0570: { KOORD k;
0571: int bs, i;
0572: char Position[16];
0573: for (bs = 0; bs < BAUSTEINZAHL; bs++) for (i = 0; i < 3; i++) if (Vorgabenwerte[bs][i][3]) {
0574: k = PosTrans3i(Hinlegen[a], Vorgabenwerte[bs][i][0], Vorgabenwerte[bs][i][1], Vorgabenwerte[bs][i][2]);
0575: Vorgabenwerte[bs][i][0] = k.KOORD[0];
0576: Vorgabenwerte[bs][i][1] = k.KOORD[1];
0577: Vorgabenwerte[bs][i][2] = k.KOORD[2];
0578: sprintf(Position, "%d,%d,%d", k.KOORD[0], k.KOORD[1], k.KOORD[2]);
0579: SetWindowText(Vorgaben[bs][i], Position);
0580: }
0581: BitteSuchen = 1;
0582: if (!SuchtGerade()) SetWindowText(SucheStart, "Suchen!");
0583: }
0584:
0585: #pragma argsused
0586: DWORD WINAPI SearchThreadProc(LPVOID dummy)
0587: { unsigned short Erg[12];
0588: unsigned long p;
0589: int a, ct, bs, i, verwerfen, halten, bed;
0590: BAUSTEIN BS;
0591: char Endstatistik[50];
0592: SearchThreadDat = NULL;
0593: while (1) {
0594: if (SearchThread_halt) {
0595: if (SearchThreadDat != NULL) fclose(SearchThreadDat); SearchThreadDat = NULL;
0596: if (!SearchThread_halted) {
0597: SearchThread_halted = 1;
0598: SendMessage(hwndApplication, WM_COMMAND, CMD_SEARCHEND, 0L);
0599: }
0600: SwitchToThread();
0601: Sleep(350);
0602: } else {
0603: if (SearchThread_start) {
0604: SearchThread_started = 1;
0605: SearchThread_start = SearchThread_halted = 0;
0606: SendMessage(hwndApplication, WM_COMMAND, CMD_ADDITEMSTRT, 0L);
0607: p = 0;
0608: if ((SearchThreadDat = fopen(ERGEBNIS, "rb")) == NULL) {
0609: SearchThread_halt = 1;
0610: } else {
0611: BitteSuchen = 0;
0612: SetWindowText(SucheStart, "Suche ...");
0613: }
0614: } else {
0615: if (fread(Erg, 24, 1, SearchThreadDat) > 0) {
0616: p++;
0617: for (a = 0; a < (SucheAlle ? 4 : 1); a++) {
0618: halten = 1;
0619: for (ct = 0; (ct < BAUSTEINZAHL) && halten; ct++) {
0620: bs = BausteinNummer(Erg[ct]);
0621: if ((bs >= 0) && (bs < BAUSTEINZAHL)) {
0622: BS = BewegterBaustein(Baustein[bs], MatMul(Hinlegen[a], Orientierung(Erg[ct])));
0623: for (bed = 0; bed < 3; bed++) if (Vorgabenwerte[bs][bed][3]) {
0624: verwerfen = 1;
0625: for (i = 0; i < BS.Teilwuerfelzahl; i++) {
0626: if ((BS.Einzelelemente[i].KOORD[0] == Vorgabenwerte[bs][bed][0])
0627: && (BS.Einzelelemente[i].KOORD[1] == Vorgabenwerte[bs][bed][1])
0628: && (BS.Einzelelemente[i].KOORD[2] == Vorgabenwerte[bs][bed][2])) verwerfen = 0;
0629: }
0630: if (verwerfen) halten = 0;
0631: }
0632: }
0633: }
0634: if (halten) {
0635: SendMessage(hwndApplication, WM_COMMAND, CMD_ADDITEM, p | (SucheAlle ? (a << 28) : 0x40000000L));
0636: }
0637: }
0638: } else {
0639: fclose(SearchThreadDat); SearchThreadDat = NULL;
0640: SearchThread_halt = 1;
0641: SetWindowText(SucheStart, BitteSuchen ? "Suchen!" : "Suchen");
0642: InvalidateRect(hwndApplication, &Bereich2, TRUE);
0643: sprintf(Endstatistik, "%u/%lu", SuchErgebnisse, p);
0644: SetWindowText(SucheStat, Endstatistik);
0645: }
0646: }
0647: }
0648: }
0649: }
0650:
0651: void StarteSuche(HWND hwnd)
0652: { int ct, bs, i;
0653: ct = 0;
0654: for (bs = 0; bs < BAUSTEINZAHL; bs++) for (i = 0; i < 3; i++) ct += Vorgabenwerte[bs][i][3];
0655: if (!ct) {
0656: MessageBox(hwnd, "Es ist unsinnig eine Filtersuche zu starten, ohne eine Bauteilbeschränkung"
0657: " eingegeben zu haben.\n\n"
0658: "Suche nicht gestartet!", "Kein Grund zur Filtersuche", MB_ICONEXCLAMATION | MB_OK);
0659: return;
0660: }
0661: SearchThread_started = 0;
0662: SearchThread_start = 1;
0663: SearchThread_halt = 0;
0664: if (SearchThread == NULL) {
0665: SearchThread = CreateThread(NULL, 0, SearchThreadProc, NULL, 0, &SearchThreadId);
0666: }
0667: do {
0668: ResumeThread(SearchThread);
0669: SearchThread_Suspend--;
0670: } while (SearchThread_Suspend > 0);
0671: if (SearchThread_Suspend < 0) SearchThread_Suspend = 0;
0672: }
0673:
0674: #pragma argsused
0675: void ScrollAction(HWND hwnd, int Notification, int Cmd, LPARAM lParam)
0676: { SCROLLINFO si;
0677: switch(Cmd) {
0678: case SB_LINEUP:
0679: if (--ScrollOffset < 0) ScrollOffset = 0;
0680: break;
0681: case SB_LINEDOWN:
0682: ScrollOffset++;
0683: if (ScrollOffset + SSl > SuchErgebnisse) ScrollOffset = SuchErgebnisse - SSl;
0684: if (ScrollOffset < 0) ScrollOffset = 0;
0685: break;
0686: case SB_PAGEUP:
0687: ScrollOffset -= SSl;
0688: if (--ScrollOffset < 0) ScrollOffset = 0;
0689: break;
0690: case SB_PAGEDOWN:
0691: ScrollOffset += SSl;
0692: if (ScrollOffset + SSl > SuchErgebnisse) ScrollOffset = SuchErgebnisse - SSl;
0693: if (ScrollOffset < 0) ScrollOffset = 0;
0694: break;
0695: case SB_THUMBTRACK:
0696: case SB_THUMBPOSITION:
0697: si.cbSize = sizeof(si);
0698: si.fMask = SIF_ALL;
0699: GetScrollInfo(SucheScroll, SB_CTL, &si);
0700: ScrollOffset = si.nTrackPos;
0701: if (ScrollOffset + SSl > SuchErgebnisse) ScrollOffset = SuchErgebnisse - SSl;
0702: if (ScrollOffset < 0) ScrollOffset = 0;
0703: if (Cmd == SB_THUMBTRACK) InvalidateRect(hwnd, &Bereich2, TRUE);
0704: break;
0705: }
0706: si.cbSize = sizeof(si);
0707: si.fMask = SIF_POS;
0708: si.nPos = ScrollOffset;
0709: SetScrollInfo(SucheScroll, SB_CTL, &si, TRUE);
0710: InvalidateRect(hwnd, &Bereich2, TRUE);
0711: }
0712:
0713: void NextScrollErg(HWND hwnd, int inc)
0714: { SCROLLINFO si;
0715: int neupos;
0716: if (!SuchErgebnisse) return;
0717: if (ChoosenResult < 0) {
0718: if (inc > 0) neupos = 0; else neupos = SuchErgebnisse - 1;
0719: } else {
0720: if (ChoosenResult + inc >= SuchErgebnisse) return;
0721: if (ChoosenResult + inc < 0) return;
0722: neupos = ChoosenResult + inc;
0723: }
0724: if (ScrollOffset > neupos) {
0725: ScrollOffset = neupos;
0726: si.cbSize = sizeof(si);
0727: si.fMask = SIF_POS;
0728: si.nPos = ScrollOffset;
0729: SetScrollInfo(SucheScroll, SB_CTL, &si, TRUE);
0730: } else
0731: if (neupos >= ScrollOffset + SSl) {
0732: ScrollOffset = neupos - SSl + 1;
0733: if (ScrollOffset < 0) ScrollOffset = 0;
0734: si.cbSize = sizeof(si);
0735: si.fMask = SIF_POS;
0736: si.nPos = ScrollOffset;
0737: SetScrollInfo(SucheScroll, SB_CTL, &si, TRUE);
0738: }
0739: SetWindowText(Loesung_Nr, ErgebnisString(neupos));
0740: ChoosenResult = neupos;
0741: InvalidateRect(hwnd, &Bereich2, TRUE);
0742: }
0743:
0744: void ZeigeHinweise(HWND hwnd)
0745: { MessageBox(hwnd,
0746: "Allgemeine Hinweise zu diesem Programm:\n\n"
0747:
0748: "- Wenn Sie eine bestimmte Lösungsnummer sehen wollen, so geben Sie die Nummer in dem Eingabefeld"
0749: " rechts oben ein. Hängen Sie noch einen Buchstaben (a bis d) an, wenn Sie auch die Gesamtorientierung"
0750: " ändern wollen.\n"
0751:
0752: "- Wollen Sie wissen, wieviele Lösungen überhaupt in der Lösungsdatei gespeichert sind, dann geben Sie einfach"
0753: " eine sehr hohe Zahl ein, sie wird automatisch herabgesetzt.\n"
0754:
0755: "- Filtervorgaben (Raumkoordinaten, an denen ein bestimmtes Puzzleteil liegen soll) können Sie auch bequem"
0756: " durch einen Mausklick (linke Taste) auf den entsprechenden Teilwürfel in der dimetrischen Darstellung"
0757: " in das Eingabefeld übernehmen.\n"
0758: "- Wenn Sie statt dessen wissen wollen, welches Puzzleteil an einer Position der angezeigten Lösung liegt,"
0759: " dann klicken Sie diesen Teilwürfel mit der rechten Maustaste an.\n"
0760:
0761: "- Änderungen der Filtereinstellung wirken sich sofort auf die laufende Filtersuche aus. Wenn Sie also die"
0762: " Filtereinstellungen ändern während die Filtersuche noch läuft, genügen die ersten Suchergebnisse anderen"
0763: " Bedingungen als die letzten Suchergebnisse.\n"
0764: "- Sie können sich die Lösung auch räumlich rotierbar ansehen. Der Aufruf des mitgelieferten Standardviewers"
0765: " (Anweisung \"neut2slp -d\") kann im Eingabefeld rechts unten ersetzt werden, um andere mit der Übergabesyntax"
0766: " kompatible Anzeigeprogramme zu starten.\n"
0767: "Nachdem Sie im mitgelieferten Standardviewer die Spachumstellung gefunden haben, werden Sie sicher auch unter"
0768: " \"Objektdarstellung\" die Möglichkeit finden, die Einzelteile des Puzzles einzeln aus- und wieder einzublenden.\n"
0769: "Die Übergabe der Platzierungpositionen der einzelen Bausteine für diesen Standardviewer steht in einer Datei"
0770: " mit der Endung \".pos\" im Unterverzeichnis \"loesungen\". Es empfiehlt sich, den Inhalt dieses"
0771: " Temporärverzeichnisses gelegentlich wieder zu löschen.\n"
0772:
0773: "\nSollten bei der Berechung der Lösungstabelle in dem Textfenster statt Umlauten seltsame Zeichen erscheinen,"
0774: " liegt das womöglich an der Zeichensatzeinstellung des 'DOS-Fensters': Rasterfont statt UNICODE-True-Type-Font.\n"
0775: "\n\xa9 Arnold Wendl, Fürth, anno Domini 2003\n\n"
0776: "P.S. Mein Testrechner war ein Pentium MMX mit 233 MHz, 192 MB RAM und Shared Memory Grafik.",
0777: ThisTitleBar " - Info", MB_ICONINFORMATION | MB_OK);
0778: }
0779:
0780: void CommandAction(HWND hwnd, int Notification, int Cmd, LPARAM lParam)
0781: { switch (Cmd) {
0782: case CMD_SUCHE:
0783: StarteSuche(hwnd);
0784: break;
0785: case CMD_SEARCHEND:
0786: SuspendThread(SearchThread);
0787: SearchThread_Suspend++;
0788: break;
0789: case CMD_SEARCHPRED:
0790: NextScrollErg(hwnd, -1);
0791: break;
0792: case CMD_SEARCHSUCC:
0793: NextScrollErg(hwnd, 1);
0794: break;
0795: case CMD_ADDITEMSTRT:
0796: ClearErgebnis();
0797: ScrollOffset = 0;
0798: AdjustScrollbarSize();
0799: break;
0800: case CMD_ADDITEM:
0801:
0802: AddErgebnis((unsigned long) lParam, 0);
0803: AdjustScrollbarSize();
0804: if (ScrollOffset + SSl >= SuchErgebnisse) InvalidateRect(hwnd, &Bereich2, TRUE);
0805: break;
0806: case CMD_FILTER:
0807: Filter_an = !Filter_an;
0808: SetSwitches();
0809: break;
0810: case CMD_ALTSUCHE:
0811: SucheAlle = !SucheAlle;
0812: BitteSuchen = 1;
0813: SetSwitches();
0814: break;
0815: case CMD_VWR_STRT:
0816: ViewerStartLoesung();
0817: break;
0818: case MN_START_SUCHE:
0819: StartLoesungsBerechnung(0);
0820: break;
0821: case MN_FILTER_CLEAR:
0822: FilterLoeschen();
0823: break;
0824: case MN_FILTER_A_B:
0825: case MN_FILTER_A_C:
0826: case MN_FILTER_A_D:
0827: FilterWenden(Cmd - MN_FILTER_CLEAR);
0828: break;
0829: case MN_INFO:
0830: ZeigeHinweise(hwnd);
0831: break;
0832: case MN_DIMET_S1:
0833: SetDimetScale(1);
0834: InvalidateRect(hwnd, &Bereich3, TRUE);
0835: break;
0836: case MN_DIMET_S2:
0837: SetDimetScale(2);
0838: InvalidateRect(hwnd, &Bereich3, TRUE);
0839: break;
0840: case MN_DIMET_S3:
0841: SetDimetScale(3);
0842: InvalidateRect(hwnd, &Bereich3, TRUE);
0843: break;
0844: case MN_MIRROR_1:
0845: Mirror1 = !Mirror1;
0846: CheckMenuItem(SpiegelMenu, MN_MIRROR_1, MF_BYCOMMAND | (Mirror1 ? MF_CHECKED : MF_UNCHECKED));
0847: InvalidateRect(hwnd, &Bereich1, TRUE);
0848: InvalidateRect(hwnd, &Bereich3, TRUE);
0849: break;
0850: case MN_MIRROR_2:
0851: Mirror2 = !Mirror2;
0852: CheckMenuItem(SpiegelMenu, MN_MIRROR_2, MF_BYCOMMAND | (Mirror2 ? MF_CHECKED : MF_UNCHECKED));
0853: InvalidateRect(hwnd, &Bereich1, TRUE);
0854: InvalidateRect(hwnd, &Bereich3, TRUE);
0855: break;
0856: case MN_MIRROR_9:
0857: Mirror9 = !Mirror9;
0858: CheckMenuItem(SpiegelMenu, MN_MIRROR_9, MF_BYCOMMAND | (Mirror9 ? MF_CHECKED : MF_UNCHECKED));
0859: InvalidateRect(hwnd, &Bereich1, TRUE);
0860: InvalidateRect(hwnd, &Bereich3, TRUE);
0861: break;
0862: case CMD_SOL_NEXT:
0863: CheckSolutionNumber(1);
0864: SelectSolutionNumber(hwnd);
0865: ChoosenResult = -1;
0866: InvalidateRect(hwnd, &Bereich2, TRUE);
0867: break;
0868: case CMD_SOL_PREV:
0869: CheckSolutionNumber(-1);
0870: SelectSolutionNumber(hwnd);
0871: ChoosenResult = -1;
0872: InvalidateRect(hwnd, &Bereich2, TRUE);
0873: break;
0874: case CMD_SOL_EDIT:
0875: switch (Notification) {
0876: case EN_UPDATE:
0877: CheckSolutionNumber(0);
0878: break;
0879: case EN_CHANGE:
0880: CheckSolutionNumber(0);
0881: SelectSolutionNumber(hwnd);
0882: ChoosenResult = -1;
0883: InvalidateRect(hwnd, &Bereich2, TRUE);
0884: break;
0885: case EN_KILLFOCUS:
0886:
0887: break;
0888: }
0889: break;
0890: default:
0891: if ((Cmd >= CMD_FB) && (Cmd - CMD_FB < 3 * BAUSTEINZAHL)) {
0892: int bs, i, x, y, z;
0893: char Box[40];
0894: switch (Notification) {
0895:
0896: case EN_CHANGE:
0897: bs = (Cmd - CMD_FB) / 3;
0898: i = (Cmd - CMD_FB) % 3;
0899: x = y = z = -1;
0900: GetWindowText(Vorgaben[bs][i], Box, 39); Box[39] = '\0';
0901: sscanf(Box, "%d,%d,%d", &x, &y, &z);
0902: if ((x < 0) || (y < 0) || (z < 0)) {
0903: Vorgabenwerte[bs][i][3] = 0;
0904: SetWindowText(FilterInfo, "Koordinate ist (noch) ungültig. Bitte Form \"x,y,z\" einhalten.");
0905: } else
0906: if (x > 4) {
0907: Vorgabenwerte[bs][i][3] = 0;
0908: SetWindowText(FilterInfo, "Koordinate ist ungültig. Bitte x-Wert zwischen 0 und 4 einhalten.");
0909: } else
0910: if (y > 3) {
0911: Vorgabenwerte[bs][i][3] = 0;
0912: SetWindowText(FilterInfo, "Koordinate ist ungültig. Bitte y-Wert zwischen 0 und 3 einhalten.");
0913: } else
0914: if (z > 2) {
0915: Vorgabenwerte[bs][i][3] = 0;
0916: SetWindowText(FilterInfo, "Koordinate ist ungültig. Bitte z-Wert zwischen 0 und 2 einhalten.");
0917: } else {
0918: Vorgabenwerte[bs][i][0] = x; Vorgabenwerte[bs][i][1] = y; Vorgabenwerte[bs][i][2] = z;
0919: Vorgabenwerte[bs][i][3] = 1;
0920: SetWindowText(FilterInfo, "");
0921: }
0922: BitteSuchen = 1;
0923: if (!SuchtGerade()) SetWindowText(SucheStart, "Suchen!");
0924: break;
0925: case EN_KILLFOCUS:
0926: VorgabeAktivBS = VorgabeAktivSp = -1;
0927: SetWindowText(FilterInfo, "");
0928: break;
0929: case EN_SETFOCUS:
0930: VorgabeAktivBS = (Cmd - CMD_FB) / 3;
0931: VorgabeAktivSp = (Cmd - CMD_FB) % 3;
0932: SetWindowText(FilterInfo, "Bitte Koordinaten in der Form \"x,y,z\" angeben. "
0933: "Oder wählen Sie rechts im Raumbild eine Position aus.");
0934: break;
0935: }
0936: }
0937: }
0938: }
0939:
0940: void Text(HDC hdc, char *Text, UINT Alignment)
0941: { POINT akt_pos;
0942: UINT TextAlign;
0943: int PrevBKM;
0944: GetCurrentPositionEx(hdc, &akt_pos);
0945: TextAlign = GetTextAlign(hdc);
0946: SetBkMode(hdc, TRANSPARENT);
0947: if (Alignment) SetTextAlign(hdc, Alignment);
0948: TextOut(hdc, akt_pos.x, akt_pos.y, Text, strlen(Text));
0949: SetTextAlign(hdc, TextAlign);
0950: SetBkMode(hdc, PrevBKM);
0951: }
0952:
0953: void Pfeil(HDC hdc, float Richtung, float Spitzwinkel, float Schenkellaenge)
0954: { POINT akt_pos[3];
0955: GetCurrentPositionEx(hdc, akt_pos);
0956: akt_pos[1].x = akt_pos[0].x
0957: + floor(Schenkellaenge * cos(M_PI * (180.0 + Richtung + 0.5 * Spitzwinkel) / 180.0) + 0.5);
0958: akt_pos[1].y = akt_pos[0].y
0959: - floor(Schenkellaenge * sin(M_PI * (180.0 + Richtung + 0.5 * Spitzwinkel) / 180.0) + 0.5);
0960: akt_pos[2].x = akt_pos[0].x
0961: + floor(Schenkellaenge * cos(M_PI * (180.0 + Richtung - 0.5 * Spitzwinkel) / 180.0) + 0.5);
0962: akt_pos[2].y = akt_pos[0].y
0963: - floor(Schenkellaenge * sin(M_PI * (180.0 + Richtung - 0.5 * Spitzwinkel) / 180.0) + 0.5);
0964: BeginPath(hdc); Polyline(hdc, akt_pos, 3); EndPath(hdc); StrokeAndFillPath(hdc);
0965: }
0966:
0967: void MoveTo3D(HDC hdc, int Ansicht, int x, int y, int z, int teiler)
0968: { int px, py;
0969: if (Ansicht > 0) {
0970: px = DI1_cx - (5 * 24 - 3 * 9) * DI_scale;
0971: py = DI1_cy - (5 * 3 + 3 * 8 - 4 * 24) * DI_scale;
0972: px += (24 * x - 9 * z) * DI_scale / teiler;
0973: py += (3 * x - 24 * y + 8 * z) * DI_scale / teiler;
0974: } else {
0975: px = DI2_cx; py = DI2_cy;
0976: px += (24 * x - 9 * z) * DI_scale / teiler;
0977: py += (24 * y - 3 * x - 8 * z) * DI_scale / teiler;
0978: }
0979: MoveToEx(hdc, px, py, NULL);
0980: }
0981:
0982: void LineTo3D(HDC hdc, int Ansicht, int x, int y, int z, int teiler)
0983: { int px, py;
0984: if (Ansicht > 0) {
0985: px = DI1_cx - (5 * 24 - 3 * 9) * DI_scale;
0986: py = DI1_cy - (5 * 3 + 3 * 8 - 4 * 24) * DI_scale;
0987: px += (24 * x - 9 * z) * DI_scale / teiler;
0988: py += (3 * x - 24 * y + 8 * z) * DI_scale / teiler;
0989: } else {
0990: px = DI2_cx; py = DI2_cy;
0991: px += (24 * x - 9 * z) * DI_scale / teiler;
0992: py += (24 * y - 3 * x - 8 * z) * DI_scale / teiler;
0993: }
0994: LineTo(hdc, px, py);
0995: }
0996:
0997: void SurfaceLine3D(HDC hdc, int Ansicht, KOORD p1, KOORD p2)
0998: { if ((Ansicht >= 0)
0999: && (((p1.KOORD[0] == 45) && (p2.KOORD[0] == 45))
1000: || ((p1.KOORD[1] == 35) && (p2.KOORD[1] == 35))
1001: || ((p1.KOORD[2] == 25) && (p2.KOORD[2] == 25)))) {
1002: MoveTo3D(hdc, 1, p1.KOORD[0] + 5, p1.KOORD[1] + 5, p1.KOORD[2] + 5, 10);
1003: LineTo3D(hdc, 1, p2.KOORD[0] + 5, p2.KOORD[1] + 5, p2.KOORD[2] + 5, 10);
1004: }
1005: if ((Ansicht <= 0)
1006: && (((p1.KOORD[0] == -5) && (p2.KOORD[0] == -5))
1007: || ((p1.KOORD[1] == -5) && (p2.KOORD[1] == -5))
1008: || ((p1.KOORD[2] == -5) && (p2.KOORD[2] == -5)))) {
1009: MoveTo3D(hdc, -1, p1.KOORD[0] + 5, p1.KOORD[1] + 5, p1.KOORD[2] + 5, 10);
1010: LineTo3D(hdc, -1, p2.KOORD[0] + 5, p2.KOORD[1] + 5, p2.KOORD[2] + 5, 10);
1011: }
1012: }
1013:
1014: void BausteinSurfaceLines3D(HDC hdc, int Ansicht, MATRIX m, int *surfaces)
1015: { int p; MATRIX M;
1016: if (surfaces == NULL) return;
1017: if (surfaces[0] >= 9999) return;
1018:
1019: M = m; for (p = 9; p < 12; p++) M.MATRIX[p] *= 10;
1020: for (p = 0; surfaces[p + 3] < 9999;) {
1021: if (surfaces[p + 3] == 2000) {
1022: p += 4;
1023: } else {
1024: SurfaceLine3D(hdc, Ansicht,
1025: PosTrans3i(M, surfaces[p ], surfaces[p + 1], surfaces[p + 2]),
1026: PosTrans3i(M, surfaces[p + 3], surfaces[p + 4], surfaces[p + 5]));
1027: p += 3;
1028: }
1029: }
1030: }
1031:
1032: void PaintLoesung(HDC hdc, int Ansicht)
1033: { HPEN Stift, altStift;
1034: int ct, bs, a, i;
1035: MATRIX m;
1036: if (!LoesungssatzGueltig) return;
1037: a = Loesungslage; if (a < 0) a = 0;
1038: altStift = GetCurrentObject(hdc, OBJ_PEN);
1039: Stift = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));
1040: SelectObject(hdc, Stift);
1041: for (ct = 0; ct < BAUSTEINZAHL; ct++) {
1042: bs = BausteinNummer(Loesungssatz[ct]);
1043: if ((bs >= 0) && (bs < BAUSTEINZAHL)) {
1044: if ((bs == 0) && Mirror1) {
1045: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV1));
1046: } else
1047: if ((bs == 1) && Mirror2) {
1048: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV2));
1049: } else
1050: if ((bs == 8) && Mirror9) {
1051: m = MatMul(Hinlegen[a], MatMul(Orientierung(Loesungssatz[ct]), INV9));
1052: } else
1053: m = MatMul(Hinlegen[a], Orientierung(Loesungssatz[ct]));
1054: BausteinSurfaceLines3D(hdc, Ansicht, m, SURFACELINES[bs]);
1055: }
1056: }
1057: SelectObject(hdc, altStift);
1058: DeleteObject(Stift);
1059: }
1060:
1061: void PaintSection3(HDC hdc)
1062: { HPEN Stift1, Stift2, alterStift;
1063: HBRUSH Farbe1, Farbe2, Farbe3, Farbe4, alteFarbe;
1064: POINT R1[4], R2[4], R3[4];
1065: int c, x, y, Ansicht;
1066: alteFarbe = GetCurrentObject(hdc, OBJ_BRUSH);
1067: alterStift = GetCurrentObject(hdc, OBJ_PEN);
1068: Farbe1 = CreateSolidBrush(RGB(224, 224, 255));
1069: Farbe2 = CreateSolidBrush(RGB(255, 255, 255));
1070: Farbe3 = CreateSolidBrush(RGB(255, 255, 224));
1071: Farbe4 = CreateSolidBrush(RGB(255, 0, 0));
1072: Stift1 = CreatePen(PS_SOLID, 0, RGB(0, 0, 255));
1073: Stift2 = CreatePen(PS_SOLID, 0, RGB(0, 255, 255));
1074:
1075: BeginPath(hdc); Rectangle(hdc, Grenze2 + 1, 1, cxScreen, cyScreen); EndPath(hdc);
1076: SelectClipPath(hdc, RGN_COPY);
1077: #define DI_cx(a) ((a > 0) ? DI1_cx : DI2_cx)
1078: #define DI_cy(a) ((a > 0) ? DI1_cy : DI2_cy)
1079: SelectObject(hdc, Farbe4);
1080: for (Ansicht = -1; Ansicht < 2; Ansicht += 2) {
1081: MoveTo3D(hdc, Ansicht, 0, 0, 0, 1); LineTo3D(hdc, Ansicht, 50 * DI_scale + 10, 0, 0, 10 * DI_scale);
1082: Text(hdc, " x", TA_BASELINE | TA_LEFT);
1083: Pfeil(hdc, -7.125 * Ansicht, 22.0, 15.0);
1084: MoveTo3D(hdc, Ansicht, 0, 0, 0, 1); LineTo3D(hdc, Ansicht, 0, 40 * DI_scale + 10, 0, 10 * DI_scale);
1085: Text(hdc, "y", ((Ansicht > 0) ? TA_BOTTOM : TA_TOP) | TA_CENTER);
1086: Pfeil(hdc, 90.0 * Ansicht, 22.0, 15.0);
1087: MoveTo3D(hdc, Ansicht, 0, 0, 0, 1); LineTo3D(hdc, Ansicht, 0, 0, 30 * DI_scale + 15, 10 * DI_scale);
1088: Text(hdc, "z", ((Ansicht > 0) ? TA_TOP : TA_BOTTOM) | TA_RIGHT);
1089: Pfeil(hdc, -138.3665 * Ansicht, 22.0, 15.0);
1090: }
1091: for (Ansicht = -1; Ansicht < 2; Ansicht += 2) {
1092:
1093: R1[0].x = DI_cx(Ansicht); R1[0].y = DI_cy(Ansicht);
1094: R1[1].x = DI_cx(Ansicht); R1[1].y = DI_cy(Ansicht) + 96 * DI_scale;
1095: R1[2].x = DI_cx(Ansicht) + 27 * DI_scale * Ansicht; R1[2].y = DI_cy(Ansicht) + 72 * DI_scale;
1096: R1[3].x = DI_cx(Ansicht) + 27 * DI_scale * Ansicht; R1[3].y = DI_cy(Ansicht) - 24 * DI_scale;
1097: R2[0].x = DI_cx(Ansicht); R2[0].y = DI_cy(Ansicht);
1098: R2[1].x = DI_cx(Ansicht) + 27 * DI_scale * Ansicht; R2[1].y = DI_cy(Ansicht) - 24 * DI_scale;
1099: R2[2].x = DI_cx(Ansicht) - 93 * DI_scale * Ansicht; R2[2].y = DI_cy(Ansicht) - 39 * DI_scale;
1100: R2[3].x = DI_cx(Ansicht) -120 * DI_scale * Ansicht; R2[3].y = DI_cy(Ansicht) - 15 * DI_scale;
1101: R3[0].x = DI_cx(Ansicht); R3[0].y = DI_cy(Ansicht);
1102: R3[1].x = DI_cx(Ansicht) -120 * DI_scale * Ansicht; R3[1].y = DI_cy(Ansicht) - 15 * DI_scale;
1103: R3[2].x = DI_cx(Ansicht) -120 * DI_scale * Ansicht; R3[2].y = DI_cy(Ansicht) + 81 * DI_scale;
1104: R3[3].x = DI_cx(Ansicht); R3[3].y = DI_cy(Ansicht) + 96 * DI_scale;
1105: SelectObject(hdc, Stift2);
1106: SelectObject(hdc, (Ansicht > 0) ? Farbe1 : Farbe3);
1107: BeginPath(hdc); Polyline(hdc, R1, 4); EndPath(hdc); FillPath(hdc);
1108: SelectObject(hdc, Farbe2);
1109: BeginPath(hdc); Polyline(hdc, R2, 4); EndPath(hdc); FillPath(hdc);
1110: SelectObject(hdc, (Ansicht > 0) ? Farbe3 : Farbe1);
1111: BeginPath(hdc); Polyline(hdc, R3, 4); EndPath(hdc); FillPath(hdc);
1112: for (c = 1; c < 3; c++) {
1113: MoveToEx(hdc, DI_cx(Ansicht) + 9 * c * DI_scale * Ansicht,
1114: DI_cy(Ansicht) + (96 - 8 * c) * DI_scale, NULL);
1115: LineTo (hdc, DI_cx(Ansicht) + 9 * c * DI_scale * Ansicht,
1116: DI_cy(Ansicht) - 8 * c * DI_scale);
1117: LineTo (hdc, DI_cx(Ansicht) + (9 * c - 120) * DI_scale * Ansicht,
1118: DI_cy(Ansicht) - (15 + 8 * c) * DI_scale);
1119: }
1120: for (c = 1; c < 4; c++) {
1121: MoveToEx(hdc, DI_cx(Ansicht) - 120 * DI_scale * Ansicht,
1122: DI_cy(Ansicht) + ( 24 * c - 15) * DI_scale, NULL);
1123: LineTo (hdc, DI_cx(Ansicht) ,
1124: DI_cy(Ansicht) + 24 * c * DI_scale);
1125: LineTo (hdc, DI_cx(Ansicht) + 27 * DI_scale * Ansicht,
1126: DI_cy(Ansicht) + ( 24 * c - 24) * DI_scale);
1127: }
1128: for (c = 1; c < 5; c++) {
1129: MoveToEx(hdc, DI_cx(Ansicht) - 24 * c * DI_scale * Ansicht,
1130: DI_cy(Ansicht) + (96 - 3 * c) * DI_scale, NULL);
1131: LineTo (hdc, DI_cx(Ansicht) - 24 * c * DI_scale * Ansicht,
1132: DI_cy(Ansicht) - 3 * c * DI_scale);
1133: LineTo (hdc, DI_cx(Ansicht) + (27 - 24 * c) * DI_scale * Ansicht,
1134: DI_cy(Ansicht) - (24 + 3 * c) * DI_scale);
1135: }
1136: SelectObject(hdc, Stift1);
1137: BeginPath(hdc); Polyline(hdc, R1, 4); EndPath(hdc); StrokePath(hdc);
1138: BeginPath(hdc); Polyline(hdc, R2, 4); EndPath(hdc); StrokePath(hdc);
1139: BeginPath(hdc); Polyline(hdc, R3, 4); EndPath(hdc); StrokePath(hdc);
1140: PaintLoesung(hdc, Ansicht);
1141: }
1142:
1143: SelectObject(hdc, alteFarbe);
1144: SelectObject(hdc, alterStift);
1145: #ifdef Ursprungskreuz
1146: MoveToEx(hdc, DI1_cx - 10, DI1_cy - 10, NULL);
1147: LineTo(hdc, DI1_cx + 10, DI1_cy + 10);
1148: MoveToEx(hdc, DI1_cx + 10, DI1_cy - 10, NULL);
1149: LineTo(hdc, DI1_cx - 10, DI1_cy + 10);
1150: MoveToEx(hdc, DI2_cx - 10, DI2_cy - 10, NULL);
1151: LineTo(hdc, DI2_cx + 10, DI2_cy + 10);
1152: MoveToEx(hdc, DI2_cx + 10, DI2_cy - 10, NULL);
1153: LineTo(hdc, DI2_cx - 10, DI2_cy + 10);
1154: #endif
1155: DeleteObject(Farbe1); DeleteObject(Farbe2); DeleteObject(Farbe3); DeleteObject(Farbe4);
1156: DeleteObject(Stift1); DeleteObject(Stift2);
1157: }
1158:
1159: void PaintIsoBS(HDC hdc, RECT *rect, int *data, int xS, int yS)
1160: { int xmin, xmax, ymin, ymax, extset = 0, p, i;
1161: POINT P[BS_ISO_MAX_POINTS];
1162: HBRUSH falt, F[3];
1163: if (hdc != NULL) {
1164: falt = GetCurrentObject(hdc, OBJ_BRUSH);
1165: F[0] = CreateSolidBrush(RGB(255, 255, 255));
1166: F[1] = CreateSolidBrush(RGB(255, 255, 0));
1167: F[2] = CreateSolidBrush(RGB( 0, 255, 255));
1168: }
1169: for (p = 0; data[p] < 9999;) {
1170: if (data[p] >= 1000) {
1171: if (data[p] < 1003) SelectObject(hdc, F[data[p] - 1000]);
1172: p++; i = 0;
1173: } else {
1174: if (extset) {
1175: if (xmin > xS + data[p]) xmin = xS +data[p]; else if (xmax < xS + data[p]) xmax = xS + data[p];
1176: if (ymin > yS - data[p+1]) ymin = yS - data[p+1]; else if (ymax < yS - data[p+1]) ymax = yS -data[p+1];
1177: } else { xmin = xmax = data[p]; ymin = ymax = yS - data[p + 1]; extset = 1; }
1178: if (hdc != NULL) { P[i].x = xS + data[p]; P[i].y = yS - data[p+1]; i++; }
1179: p += 2;
1180: }
1181: if ((hdc != NULL) && (data[p] >= 1000)) {
1182: BeginPath(hdc);
1183: Polyline(hdc, P, i);
1184: EndPath(hdc);
1185: StrokeAndFillPath(hdc);
1186: i = 0;
1187: }
1188: }
1189: if (rect != NULL) {
1190: rect->top = ymin; rect->bottom = ymax; rect->left = xmin; rect->right = xmax;
1191: }
1192: if (hdc != NULL) {
1193: SelectObject(hdc, falt);
1194: for (i = 0; i < 3; i++) DeleteObject(F[i]);
1195: }
1196: }
1197:
1198: void PaintSection2(HDC hdc)
1199: { int y, ct, bkm, crf;
1200: RECT r;
1201: r.left = Grenze1 + 1; r.right = SSx;
1202: bkm = SetBkMode(hdc, TRANSPARENT);
1203: for (ct = 0; ct < SSl; ct++) {
1204: r.top = SSy + ct * TXy;
1205: r.bottom = r.top + TXy;
1206: if (ct + ScrollOffset == ChoosenResult) crf = SetTextColor(hdc, RGB(255, 0, 0));
1207: DrawText(hdc, ErgebnisString(ct + ScrollOffset), -1, &r, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1208: if (ct + ScrollOffset == ChoosenResult) SetTextColor(hdc, crf);
1209: }
1210: SetBkMode(hdc, bkm);
1211: }
1212:
1213: void PaintSection1(HDC hdc)
1214: { int y, b; RECT r;
1215: char RectInfo[300];
1216: HPEN altstift, stift;
1217: COLORREF bkcolor;
1218: altstift = GetCurrentObject(hdc, OBJ_PEN);
1219: bkcolor = GetBkColor(hdc);
1220: stift = CreatePen(PS_DOT, 0, RGB(0, 0, 0));
1221: SetBkColor(hdc, RGB(255, 255, 128));
1222: y = EWB1;
1223: for (b = 0; b < BAUSTEINZAHL; b++) {
1224: if (b == MarkierterBS) {
1225: MoveToEx(hdc, 0, y - EHD / 2, NULL);
1226: LineTo(hdc, PictWidth1, y - EHD / 2);
1227: LineTo(hdc, PictWidth1, y + EHD / 2);
1228: LineTo(hdc, 0 , y + EHD / 2);
1229: LineTo(hdc, 0 , y - EHD / 2);
1230: }
1231: if (((b == 0) && Mirror1) || ((b == 1) && Mirror2) || ((b == 8) && Mirror9)) {
1232: SelectObject(hdc, stift);
1233: MoveToEx(hdc, PictWidth1 / 2 + 4 * EHD / 7, y - EHD / 2, NULL);
1234: LineTo( hdc, PictWidth1 / 2 - 4 * EHD / 7, y + EHD / 2);
1235: SelectObject(hdc, altstift);
1236: }
1237: PaintIsoBS(NULL, &r, BS_ISO[b], 0, 0);
1238: PaintIsoBS(hdc, NULL, BS_ISO[b], (PictWidth1 - r.right + r.left) / 2, y + (r.bottom - r.top) / 2);
1239: sprintf(RectInfo, "{ l=%d, r=%d, t=%d, b=%d } -> %d, %d\n",
1240: r.left, r.right, r.top, r.bottom, (PictWidth1 - r.right + r.left) / 2, y + (r.bottom - r.top) / 2);
1241: y += EHD;
1242: }
1243: SetBkColor(hdc, bkcolor);
1244: DeleteObject(stift);
1245: }
1246:
1247: void PaintGlobal(HDC hdc)
1248: { HPEN stift1, stift2, altstift;
1249: altstift = GetCurrentObject(hdc, OBJ_PEN);
1250: stift1 = CreatePen(PS_SOLID, 0, RGB(255, 255, 255));
1251: stift2 = CreatePen(PS_SOLID, 0, RGB( 0, 0, 128));
1252: SelectObject(hdc, stift2);
1253: MoveToEx(hdc, Grenze1, 0, NULL); LineTo(hdc, Grenze1, cyScreen);
1254: MoveToEx(hdc, Grenze2, 0, NULL); LineTo(hdc, Grenze2, cyScreen);
1255: SelectObject(hdc, stift1);
1256: MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, cxScreen, 0);
1257: SelectObject(hdc, altstift);
1258: DeleteObject(stift1); DeleteObject(stift2);
1259: }
1260:
1261: void SucheBSaufPos(int x, int y, int z)
1262: { char Mldg[200];
1263: int bs, ct, a, i;
1264: BAUSTEIN BS;
1265: MarkierterBS = -1;
1266: if (!LoesungssatzGueltig) return;
1267: a = Loesungslage; if (a < 0) a = 0;
1268: for (ct = 0; ct < BAUSTEINZAHL; ct++) {
1269: bs = BausteinNummer(Loesungssatz[ct]);
1270: if ((bs >= 0) && (bs < BAUSTEINZAHL)) {
1271: BS = BewegterBaustein(Baustein[bs], MatMul(Hinlegen[a], Orientierung(Loesungssatz[ct])));
1272: for (i = 0; i < BS.Teilwuerfelzahl; i++) {
1273: if ((BS.Einzelelemente[i].KOORD[0] == x)
1274: && (BS.Einzelelemente[i].KOORD[1] == y)
1275: && (BS.Einzelelemente[i].KOORD[2] == z)) {
1276: MarkierterBS = bs;
1277: InvalidateRect(hwndApplication, &Bereich1, TRUE);
1278: sprintf(Mldg, "Der %d. Baustein liegt auf der Raumkoordinate '%d,%d,%d'",
1279: bs + 1, x, y, z);
1280: MessageBox(hwndApplication, Mldg, "Positionsinfo:", MB_ICONINFORMATION | MB_OK);
1281: return;
1282: }
1283: }
1284: }
1285: }
1286: InvalidateRect(hwndApplication, &Bereich1, TRUE);
1287: }
1288:
1289: void SetFilterCoordinate(int x, int y, int z)
1290: { char Positionsstring[16];
1291: if (!Filter_an || (VorgabeAktivBS < 0) || (VorgabeAktivSp < 0)) return;
1292: sprintf(Positionsstring, "%d,%d,%d", x, y, z);
1293: SetWindowText(Vorgaben[VorgabeAktivBS][VorgabeAktivSp], Positionsstring);
1294: Vorgabenwerte[VorgabeAktivBS][VorgabeAktivSp][0] = x;
1295: Vorgabenwerte[VorgabeAktivBS][VorgabeAktivSp][1] = y;
1296: Vorgabenwerte[VorgabeAktivBS][VorgabeAktivSp][2] = z;
1297: Vorgabenwerte[VorgabeAktivBS][VorgabeAktivSp][3] = 1;
1298: BitteSuchen = 1;
1299: if (!SuchtGerade()) SetWindowText(SucheStart, "Suchen!");
1300: }
1301:
1302: void ButtonPosClickSelect(HWND hwnd, int x, int y)
1303: { int p;
1304: if ((x <= Grenze1) || (x >= Grenze2)) return;
1305: p = y - SSy;
1306: if (p < 0) return;
1307: p = p / TXy;
1308: if (p >= SSl) return;
1309: p += ScrollOffset;
1310: if (p >= SuchErgebnisse) return;
1311:
1312: SetWindowText(Loesung_Nr, ErgebnisString(p));
1313: ChoosenResult = p;
1314: InvalidateRect(hwnd, &Bereich2, TRUE);
1315: }
1316:
1317: void ButtonPosClickTransfer(HWND hwnd, int to_filter, int x, int y)
1318: { int dx, dy, u, v;
1319: if (x < Grenze2) return;
1320:
1321:
1322: dx = x - DI1_cx; dy = y - DI1_cy;
1323:
1324: u = ( 3 * dx - 24 * dy + 219 * DI_scale) / 219 / DI_scale - 1;
1325: v = ( -8 * dx - 9 * dy + 219 * DI_scale) / 219 / DI_scale - 1;
1326: if ((u >= 0) && (v >= 0) && (u < 3) && (v < 5)) {
1327: if (!to_filter) { SucheBSaufPos(4 - v, 3, 2 - u); return; }
1328: SetFilterCoordinate(4 - v, 3, 2 - u);
1329: return;
1330: }
1331:
1332: u = (-24 * dx + 576 * DI_scale) / 576 / DI_scale - 1;
1333: v = ( -3 * dx + 24 * dy + 576 * DI_scale) / 576 / DI_scale - 1;
1334: if ((u >= 0) && (v >= 0) && (u < 5) && (v < 4)) {
1335: if (!to_filter) { SucheBSaufPos(4 - u, 3 - v, 2); return; }
1336: SetFilterCoordinate(4 - u, 3 - v, 2);
1337: return;
1338: }
1339:
1340: u = ( 24 * dx + 216 * DI_scale) / 216 / DI_scale - 1;
1341: v = ( 8 * dx + 9 * dy + 216 * DI_scale) / 216 / DI_scale - 1;
1342: if ((u >= 0) && (v >= 0) && (u < 3) && (v < 4)) {
1343: if (!to_filter) { SucheBSaufPos(4, 3 - v, 2 - u); return; }
1344: SetFilterCoordinate(4, 3 - v, 2 - u);
1345: return;
1346: }
1347:
1348: dx = x - DI2_cx; dy = y - DI2_cy;
1349:
1350: u = ( 8 * dx - 9 * dy + 219 * DI_scale) / 219 / DI_scale - 1;
1351: v = ( -3 * dx - 24 * dy + 219 * DI_scale) / 219 / DI_scale - 1;
1352: if ((u >= 0) && (v >= 0) && (u < 5) && (v < 3)) {
1353: if (!to_filter) { SucheBSaufPos(u, 0, v); return; }
1354: SetFilterCoordinate(u, 0, v);
1355: return;
1356: }
1357:
1358: u = (-24 * dx + 216 * DI_scale) / 216 / DI_scale - 1;
1359: v = ( -8 * dx + 9 * dy + 216 * DI_scale) / 216 / DI_scale - 1;
1360: if ((u >= 0) && (v >= 0) && (u < 3) && (v < 4)) {
1361: if (!to_filter) { SucheBSaufPos(0, v, u); return; }
1362: SetFilterCoordinate(0, v, u);
1363: return;
1364: }
1365:
1366: u = ( 24 * dx + 567 * DI_scale) / 576 / DI_scale - 1;
1367: v = ( 3 * dx + 24 * dy + 576 * DI_scale) / 576 / DI_scale - 1;
1368: if ((u >= 0) && (v >= 0) && (u < 5) && (v < 4)) {
1369: if (!to_filter) { SucheBSaufPos(u, v, 0); return; }
1370: SetFilterCoordinate(u, v, 0);
1371: return;
1372: }
1373: if (!to_filter) { MarkierterBS = -1; InvalidateRect(hwnd, &Bereich1, TRUE); }
1374: }
1375:
1376: LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1377: { HDC hdc;
1378: PAINTSTRUCT ps;
1379: switch (uMsg) {
1380: case WM_PAINT:
1381: hdc = BeginPaint(hwnd, &ps);
1382: PaintGlobal(hdc);
1383: PaintSection1(hdc);
1384: PaintSection2(hdc);
1385: PaintSection3(hdc);
1386: EndPaint(hwnd, &ps);
1387: return 0;
1388: case WM_CREATE:
1389: cxChar = LOWORD(GetDialogBaseUnits());
1390: cyChar = HIWORD(GetDialogBaseUnits());
1391: CreateSubwindows(hwnd);
1392: break;
1393: case WM_SIZE:
1394: cxScreen = LOWORD(lParam);
1395: cyScreen = HIWORD(lParam);
1396: ChangeSize(hwnd, lParam);
1397: AdjustScrollbarSize();
1398: break;
1399: case WM_COMMAND:
1400: CommandAction(hwnd, HIWORD(wParam), LOWORD(wParam), lParam);
1401: break;
1402: case WM_VSCROLL:
1403: ScrollAction(hwnd, HIWORD(wParam), LOWORD(wParam), lParam);
1404: break;
1405: case WM_RBUTTONDOWN:
1406: ButtonPosClickTransfer(hwnd, 0, LOWORD(lParam), HIWORD(lParam));
1407: break;
1408: case WM_LBUTTONDOWN:
1409: ButtonPosClickTransfer(hwnd, 1, LOWORD(lParam), HIWORD(lParam));
1410: ButtonPosClickSelect(hwnd, LOWORD(lParam), HIWORD(lParam));
1411: break;
1412: case WM_DESTROY:
1413: if (Loesungsdatei != NULL) fclose(Loesungsdatei);
1414: PostQuitMessage(0);
1415: return 0;
1416: }
1417: return DefWindowProc(hwnd, uMsg, wParam, lParam);
1418: }
1419:
1420: BOOL InsertSubmenuString(HMENU hMenu, UINT Pos, BOOL byPos, HMENU submenu, CHAR *Text)
1421: { MENUITEMINFO mii;
1422: mii.cbSize = sizeof(MENUITEMINFO);
1423: mii.fMask = MIIM_SUBMENU | MIIM_TYPE;
1424: mii.fType = MFT_STRING;
1425: mii.fState = MFS_DEFAULT;
1426: mii.wID = 0;
1427: mii.hSubMenu= submenu;
1428: mii.hbmpChecked = NULL;
1429: mii.hbmpUnchecked = NULL;
1430: mii.dwItemData = 0;
1431: mii.dwTypeData = Text;
1432: mii.cch = strlen(Text);
1433: return InsertMenuItem(hMenu, Pos, byPos, &mii);
1434: }
1435:
1436: void BuildMenu(HWND hwnd)
1437: { HMENU newmenu, oldmenu, submenu;
1438:
1439: newmenu = CreateMenu();
1440:
1441: AppendMenu(newmenu, MF_STRING, MN_START_SUCHE, "&Lösungssuche starten");
1442:
1443: SpiegelMenu = CreateMenu();
1444: AppendMenu(SpiegelMenu, MF_STRING, MN_MIRROR_1, "&C-Teil umdrehen");
1445: AppendMenu(SpiegelMenu, MF_STRING, MN_MIRROR_2, "&Z-Teil umdrehen");
1446: AppendMenu(SpiegelMenu, MF_STRING, MN_MIRROR_9, "&r-Teil umdrehen");
1447: InsertSubmenuString(newmenu, -1, TRUE, SpiegelMenu, "&Bausteinspiegelungen");
1448:
1449: submenu = CreateMenu();
1450: AppendMenu(submenu, MF_STRING, MN_FILTER_CLEAR, "alle Filter &löschen");
1451: AppendMenu(submenu, MF_STRING, MN_FILTER_A_B, "wenden a/&b und c/d");
1452: AppendMenu(submenu, MF_STRING, MN_FILTER_A_C, "wenden a/&c und b/d");
1453: AppendMenu(submenu, MF_STRING, MN_FILTER_A_D, "wenden a/&d und b/c");
1454: InsertSubmenuString(newmenu, -1, TRUE, submenu, "&Filtermanipulationen");
1455:
1456: DimetrieMenu = CreateMenu();
1457: AppendMenu(DimetrieMenu, MF_STRING, MN_DIMET_S1, "Zoomfaktor &1");
1458: AppendMenu(DimetrieMenu, MF_STRING, MN_DIMET_S2, "Zoomfaktor &2");
1459: AppendMenu(DimetrieMenu, MF_STRING, MN_DIMET_S3, "Zoomfaktor &3");
1460: InsertSubmenuString(newmenu, -1, TRUE, DimetrieMenu, "&Dimetrische Darstellungen");
1461:
1462: AppendMenu(newmenu, MF_STRING, MN_INFO, "&Hinweise");
1463:
1464: oldmenu = GetMenu(hwnd);
1465: SetMenu(hwnd, newmenu);
1466: DestroyMenu(oldmenu);
1467: DrawMenuBar(hwnd);
1468: }
1469:
1470: #pragma argsused
1471: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR d3, int nCmdShow)
1472: {
1473: MSG msg;
1474: WNDCLASSEX wndClass;
1475:
1476:
1477: hThisInstance = hInstance;
1478: IconGross = CreateIconString(hInstance, 32, 32, 2, 2, 0,
1479: " "
1480: " "
1481: "KKKKKKKKKKKKKKKK"
1482: "K..K..KRRKR.K..K"
1483: "K..K..KRRKR.K..K"
1484: "KKKKKKK.RKR.KKKK"
1485: "K..RRRK.RKRRRRRK"
1486: "K.R...KR.KR....K"
1487: "KR.KKKKKKKR.KKKK"
1488: "KR.K.....KR.K..K"
1489: "KR.K.....KR.K..K"
1490: "KR.KKKKKKKR.KKKK"
1491: "K.R...K..K.R...K"
1492: "K..RRRK..K..RRRK"
1493: "KKKKKKKKKKKKKKKK"
1494: " ");
1495: IconKlein = CreateIconString(hInstance, 16, 16, 1, 1, 0,
1496: " "
1497: " "
1498: "KKKKKKKKKKKKKKKK"
1499: "K..K..KRRKR.K..K"
1500: "K..K..KRRKR.K..K"
1501: "KKKKKKK.RKR.KKKK"
1502: "K..RRRK.RKRRRRRK"
1503: "K.R...KR.KR....K"
1504: "KR.KKKKKKKR.KKKK"
1505: "KR.K.....KR.K..K"
1506: "KR.K.....KR.K..K"
1507: "KR.KKKKKKKR.KKKK"
1508: "K.R...K..K.R...K"
1509: "K..RRRK..K..RRRK"
1510: "KKKKKKKKKKKKKKKK"
1511: " ");
1512: if (hPrevInstance == NULL) {
1513: memset(&wndClass, 0, sizeof(WNDCLASSEX));
1514: wndClass.cbSize = sizeof(WNDCLASSEX);
1515: wndClass.style = CS_HREDRAW | CS_VREDRAW;
1516: wndClass.lpfnWndProc = WndProc;
1517: wndClass.cbClsExtra = 0;
1518: wndClass.cbWndExtra = 0;
1519: wndClass.hInstance = hInstance;
1520: wndClass.hIcon = IconGross;
1521: wndClass.hIconSm = IconKlein;
1522: wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
1523: wndClass.hbrBackground = (HBRUSH) (COLOR_MENU + 1);
1524: wndClass.lpszMenuName = NULL;
1525: wndClass.lpszClassName = ThisClassName;
1526: if (!RegisterClassEx(&wndClass)) {
1527: MessageBox(NULL, "RegisterClass() schlug fehl!", "Prinzipielle Startprobleme",
1528: MB_ICONEXCLAMATION | MB_OK);
1529: return 1;
1530: }
1531: }
1532:
1533: HintergrundLeiste = CreateSolidBrush(RGB(0, 0, 128));
1534:
1535: hwndApplication = CreateWindow(ThisClassName, ThisTitleBar,
1536: WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
1537: CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
1538: NULL, NULL, hInstance, NULL);
1539: BuildMenu(hwndApplication);
1540: SetDimetScale(1);
1541: ShowWindow(hwndApplication, nCmdShow);
1542: UpdateWindow(hwndApplication);
1543: if (access(ERGEBNIS, 4)) StartLoesungsBerechnung(1);
1544:
1545: while (GetMessage(&msg, NULL, 0, 0)) {
1546: TranslateMessage(&msg);
1547: DispatchMessage(&msg);
1548: }
1549:
1550: return msg.wParam;
1551: }
1552:
1553: