Struct ändern
-
void checkPOINT (POINT **point) { int num = 10; *point = (POINT *) malloc (num * sizeof (POINT)); (*point)[0].x = (*point)[0].y = 10; (*point)[1].x = (*point)[1].y = 0; (*point)[2].x = (*point)[2].y = 20; (*point)[3].x = (*point)[3].y = 30; (*point)[4].x = (*point)[4].y = 0; (*point)[5].x = (*point)[5].y = 40; (*point)[6].x = (*point)[6].y = 50; (*point)[7].x = (*point)[7].y = 0; (*point)[8].x = (*point)[8].y = 70; (*point)[9].x = (*point)[9].y = 80; for (int i = 0; i < num; i++) { if ((*point)[i].x <= 1 || (*point)[i].y <= 1) { memmove (&(*point)[i], &(*point)[i + 1], ((10 - i - 1) * sizeof (POINT))); num--; } } } int _tmain(int argc, _TCHAR* argv[]) { POINT *paperSizes = NULL; checkPOINT (&paperSizes); wprintf (L"\n\n"); for (int i = 0; i < 8; i++) wprintf (L"%i %i\n", paperSizes[i].x, paperSizes[i].y); return 0; }
Das habe ich gerade mal in einer extra Konsolendatei getestet und funktioniert auch. In meinem richtigen Programm stützt das so (mittlerweile) immer ab (habs eins zu eins kopiert). Minimalbeispiel ist da schlecht für ...
Aber so ist ungefähr der Aufbau:
dlg.cpp <-- checkPOINT () --- function.cpp
checkPOINT ist in function.cpp definiert. In dlg.cpp wird die Funktion aus einer anderen Funktion heraus aufgerufen, in der wiederum der POINT-Pointer zu Hause ist. Der ist auch auf static, also ohne memmove ist mit den Daten darin alles gut, bis auf die nullen. Der POINT-Pointer wird auch nur in der Funktion benutzt, die checkPOINT aufruft ...
-
habe es doch noch auf ein minimales bekommen wo es immer noch abstürzt:
#include "stdafx.h" #include <Windows.h> int getPaperSize (wchar_t *str_printerName, wchar_t *str_printerPort, POINT **pt_paperSizes) { unsigned short epserr = 0; int numPaperSizes = DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERSIZE, NULL, NULL); if (numPaperSizes == -1) return -1; *pt_paperSizes = (POINT *) malloc (numPaperSizes * sizeof (POINT)); int returnVal = DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERSIZE, (LPWSTR) *pt_paperSizes, NULL); if ((returnVal == -1)) { free (*pt_paperSizes); *pt_paperSizes = NULL; return -1; } for (int i = 0; i < returnVal; i++) { if ((*pt_paperSizes)[i].x <= 1 || (*pt_paperSizes)[i].y <= 1) { memmove (&(*pt_paperSizes)[i], &(*pt_paperSizes)[i + 1], ((10 - i - 1) * sizeof (POINT))); returnVal--; } } return epserr; } int _tmain(int argc, _TCHAR* argv[]) { POINT *paperSizes = NULL; getPaperSize (L"Fax\0", L"\0", &paperSizes); wprintf (L"\n\n"); for (int i = 0; i < 8; i++) wprintf (L"%i %i\n", paperSizes[i].x, paperSizes[i].y); free (paperSizes); return 0; }
-
for (int i = 0; i < returnVal; i++) { if ((*pt_paperSizes)[i].x <= 1 || (*pt_paperSizes)[i].y <= 1) { memmove (&(*pt_paperSizes)[i], &(*pt_paperSizes)[i + 1], ((returnVal - i - 1) * sizeof (POINT))); //Muss "returnVal" sein statt "10", sonst kommt was negatives raus i--; //Das aktuelle Element muss wiederholt werden, da es jetzt ein neuer Punkt ist returnVal--; } } return returnVal; //Richtigen Wert zurückgeben?
-
Das erklärt schonmal, warum es auf einmal doch abgestürzt ist. Böses copy/paste ... Da erkläre ich das oben so schön und haue statt der Gesamtanzahl die blöde zehn rein
Das mit dem akutellen i war wohl dann der Grund, warum nichts richtig gelöscht wurde! Also danke vielmals!!
-
int EnumerateSupportedPapers (HWND combobox, wchar_t *str_printerName, wchar_t *str_printerPort, POINT **pt_paperSizes, PAPERNAME *arr_paperNames, int count_paperNames) { unsigned short epserr = EPSERR_NOERROR; SendMessage (combobox, CB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0); int numPapers = DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERS, NULL, NULL); int numPaperNames = DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERNAMES, NULL, NULL); int numPaperSizes = DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERSIZE, NULL, NULL); if (numPapers == -1 || numPaperNames == -1 || numPaperSizes == -1) return EPSERR_FAILEDTOENUMPAPERS; unsigned short *dw_papers = (unsigned short*) malloc (numPapers * sizeof (unsigned short)); wchar_t *str_paperNames = (wchar_t*) malloc (64 * numPaperNames * sizeof (wchar_t)); *pt_paperSizes = (POINT *) malloc (numPaperSizes * sizeof (POINT)); if ((DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERS, (LPWSTR) dw_papers, NULL) == -1) || (DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERNAMES, str_paperNames, NULL) == -1) || (DeviceCapabilities (str_printerName, str_printerPort, DC_PAPERSIZE, (LPWSTR) *pt_paperSizes, NULL) == -1)) { free (dw_papers); free (str_paperNames); free (*pt_paperSizes); *pt_paperSizes = NULL; return EPSERR_FAILEDTOENUMPAPERS; } wchar_t str_currentName[64 + 1]; str_currentName[64] = L'\0'; SendMessage (combobox, CB_ADDSTRING, (WPARAM) 0, (LPARAM) L"Benutzerdefiniert..."); for (int i = 0, paperSizeIndex = 0; i < numPaperSizes; i++) { bool b_paperFound = false; if ((*pt_paperSizes)[paperSizeIndex].x <= 1 || (*pt_paperSizes)[paperSizeIndex].y <= 1) { memmove (&(*pt_paperSizes)[paperSizeIndex], &(*pt_paperSizes)[paperSizeIndex + 1], ((numPaperSizes - paperSizeIndex - 1) * sizeof (POINT))); continue; } for (int x = 0; x < count_paperNames; x++) { if ((&arr_paperNames[x])->id == dw_papers[i]) { unsigned long retValue = SendMessage (combobox, CB_ADDSTRING, (WPARAM) 0, (LPARAM) (&arr_paperNames[x])->strName); if (retValue == CB_ERR || retValue == CB_ERRSPACE) epserr = EPSERR_FAILEDTOLISTPAPERS; b_paperFound = true; } } if (!b_paperFound) { memcpy (str_currentName, str_paperNames + (i * 64), 64 * sizeof (wchar_t)); unsigned long retValue = SendMessage (combobox, CB_ADDSTRING, (WPARAM) 0, (LPARAM) str_currentName); if (retValue == CB_ERR || retValue == CB_ERRSPACE) epserr = EPSERR_FAILEDTOLISTPAPERS; } paperSizeIndex++; } free (dw_papers); free (str_paperNames); return epserr; }
Habe es über ein extra Index für die POINTs programmiert, weil ich in der Schleife noch andere Sachen machen muss. Falls das jemand sehen will habe ich den ganzen Code mit reingepackt
Danke an Euch für die Hilfe hätte sonst bestimmt Sonntag noch dran gesessen ^^
-
Nur um ganz sicher zu gehen: Dir ist klar, dass sofern die Reihenfolge der Elemente keine Rolle spielen sollte, das ganze auch wesentlich weniger aufwendig für den Computer ginge? Das häufige Verschieben ist nämlich recht teuer. Und ganz unabhängig von der Relevanz der Reihenfolge: Wenn man öfters Löschungen in der Mitte eines Arrays hat, lohnt es sich nachzudenken, ob ein Array überhaupt die richtige Datenstruktur ist.
-
leider kann man die größe der papierformate nachträglich bzw. nur für ein spezielles format nicht ermitteln (ich weiß wenigstens nicht wie), sodass ich das anders nicht gelöst bekommen habe gedanklich ... also ich kann wenn ich die größe von din a6 haben will nirgends eine funktion aufrufen um die sicher zu ermitteln. das läuft dann immer über strings und die sind bei jedem drucker anders, aber DC_PAPERS und DC_PAPERSIZE stimmen vom index her überein (auch laut msdn), so dass ich immer nur den index der auswahl in der combobox ermitteln muss und dann im POINT array nachgucken kann, welche größe das ist.
DeviceCapabilities gibt beim ermitteln der papiergröße immer ein POINT array zurück, also müsste ich das wenn dann umwandeln und da nur ganz wenig gelöscht werden müssen pro aufruf finde ich das in ordnung. es sind vielleicht mal zwei von 50 oder so ... wenn da irgendwie trotzdem eine andere lösung besser ist lasse ich mich gerne darauf ein
-
Und gerade getestet: ob mit oder ohne memmove: GetTickCount sagt 16ms von anfang bis ende der funktion ... ist also in dem fall wohl wirklich egal ... bisher habe ich auch nur bei Fax werte gesehen, die == 0 sind und daher ist das wohl eine ziemliche ausnahme ... alle anderen drucker haben keine 0 werte die ich aufgelistet habe
-
GetTickCount ist recht ungenau. Verwende lieber den Performance-Timer.
-
Solange die Funktion nicht extrem oft aufgerufen wird ist die Performance doch eh schnurz. Das sind ein paar Bytes die im RAM kopiert werden, da ist es sinnvoller dass der Code übersichtlich ist.