Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Bloodsheddev c++ win xp - drukowanie

04 Sty 2007 01:21 2308 12
  • Poziom 28  
    Poszukałem nieco na forum i na googlach, ale bez zadowalających rezultatów.

    Chciałbym drukować na drukarce domyślnej tekst, ale nie udało mi się odpalić żadnych przykładów zamieszczonych na stronkach. Potrzebna jest jakaś maksymalnie prosta metoda bez winapi. Może ma ktoś działające źródełko pod Bloodsheddev c++, które mu zachulało pod windą?

    Dzięki za odpowiedzi.
  • Poziom 15  
    Słuchaj, podam bardzo prymitywna metodę, ale dla mnie wystarczającą:
    Code:
    #include <stdio.h>
    
    #include <stdlib.h>

    int main ( void )
    {
        FILE* text = fopen("text.txt", "w");
        fputs( "Tekst do wydrukowania.", text );
        fclose(text);
        system("print text.txt");
        return 0;
    }

    Korzystam tu z DOS'owego polecenia "print [dir]", gdzie dir to ścieżka pliku do wydruku w trybie tekstowym.
  • Poziom 29  
    No więc... U mnie to polecenie nie działa :P W każdym razie program się zawiesza i tyle. Drukarka nie odpowiada... :P
  • Poziom 28  
    Spoko kodzik. Jeszcze nie sprawdzałem, bo przespałem cały dzień (w tym tygodniu &^$^%$ nocki). A masz jakiś pomysł, żeby obsłużyć drukarkę w trybie wierszowym? Najlepiej pasowałoby mi żeby móc drukować wyniki pracy programu na bierząco (w tym przyopadku będą to wyniki pomiarów) - jako jakby kopia zapasowa. Sprzęt będzie narażony na częste zaniki zasilania.
  • Poziom 15  
    Jedyny sposób jaki znam, by nie dopuścić do utraty danych, to każdorazowe otwarcie, zapis wiersza, i zamknięcie pliku przez fclose(...); Wtedy dane sś zachowane na dysku, i wystarczy tylko dopisać opcję menu programowego by drukował raporty. Poniżej zamieszczam przykładowy kod tym razem w C:
    Code:
    #include <stdio.h>
    
    #include <stdlib.h>

    #define _stdfile "stdout.log"
    #define _print "print stdout.log"

    void send( const char* _data, const char* _when ){
        FILE* fp = fopen(_when, "a+");  // "a+" - nadpisz
        fputs(_data, fp);
        fclose(fp);
    }
    int main ( void )
    {
        send("Start raportow\nPress any key\n", _stdfile);
        while ( !kbhit() ){ // Czeka na klawisz
                 // Nawet jesli tu wystapi błąd i zwis, dane wcześniejsze zostaną
                 // na dysku
              }
        send("Koniec", _stdfile);
        // system (_print);
        return 0;
    }
  • Specjalista techniki cyfrowej
    Freeradio napisał:
    Jedyny sposób jaki znam, by nie dopuścić do utraty danych, to każdorazowe otwarcie, zapis wiersza, i zamknięcie pliku przez fclose(...); Wtedy dane sś zachowane na dysku, i wystarczy tylko dopisać opcję menu programowego by drukował raporty.


    Niekoniecznie musi to działać, ale zawsze to odrobine bezpieczniej niż trzymanie cały czas otwartego pliku.
    Współczesne (a nawet i dość stare) systemy operacyjne, a także same napędy posiadają bufory, w których przetrzymują dane przeznaczone do zapisania aż do czasu gdy uzbiera się odpowiednia ich ilość, co powoduje dość znaczyny wzrost szybkości zapisu.
    Tak dla przykładu całkowicie niebuforowany zapis danych po jednym bajcie na dysku o prędkości obrotowej 7200 RPM wykonywany był by z prędkością 120B/s :]
    Awaria zasilania spowoduje że dane zgromadzone w pamieci cache dysku, czy też te zgromadzone przez system operacyjny nie zostaną zapisane.
    Chyba wszystkie systemy operacyjne, które posiadają jakiekolwiek buforowanie opróżniają bufor w momencie zamknięcia pliku, lub wydania odpowiedniego ploecenia (fflush() w standardzie POSIX).
    Tak więc częste zamykanie pliku zmniejsza prawdopodobieństwo utraty danych, podobnie zadziała fflush() w połączeniu z systemem plików oferujących pełny journaling, z tym że w tym wypadku na pewno nie dojdzie do 'zaśmiecenia' pliku, a być może dane uda się uratować. NTFS ma journal, ale nie wiem czy pełny, FAT nie ma.

    Problem jest natomiast z samym dyskiem, co więcej, w starszych wersjach windows (do '98 bez jakiejś tam poprawki) występował błąd polegający na tym, że system operacyjny nie czekał dostatecznie długo aż dysk zapisze zawartość swojego cache'u i wyłączał zasilanie (na płytach ATX).
    Praktycznie każdy dysk który posiada pamięć cache ma polecenie służące do jej opróżnienia, obawiam się tylko że bezpośrednie wysłanie polecenia do dysku będzie niemożliwe nawet gdy program zostanie uruchomiony z uprawnieniami administratora. No chyba że sam system przewiduje taką możliwość, nie wiem, nie wgłębiałem się w ten temat.

    A wracając do drukarki, przede wszystkim drukowanie 'w locie' będzie działać tylko na drukarkach mających możliwość druku na papierze ciągłym. Na pewno nie zadziała na drukarce laserowej, która musi napierw mieć całą stronę w buforze (albo przynajmniej otrzymywać dane tak szybko, żeby nie opróżniła bufora przed wydrukowaniem całej strony), bo w takiej drukarce nie można zatrzymać papieru wewnątrz mechanizmu, bo w skrajnym przypadku grozi to pożarem :].
    Drukarki atramentowe mogą zatrzymać sięw połowie wydruku, a potem kontynuować, ale najczęściej taka sytuacja ma miejsce dlatego, że bufor w drukarce jest zbyt mały zeby zmieściał się w nim cała strona, a komputer przesyła dane zbyt wolno, drukarka natomiast zaczyna drukowanie po zapełnieniu swojego bufora, lub po przesłaniu całej strony (chociaż chyba nic nie stoi na przeszkodzie żeby zaczęła drukować odrazu, ale kiedyś mojego Canona ip3000 testowałem i czekała albo na całą stronę, albo na koniec danych).
    Pozostaje więc tylko drukarka igłowa.

    Osobiście uskuteczniałem metodę polegającą na zapisie do urządzenia logicznego PRN:

    Kod przed chwilą sprawdzony i działa:
    Code:
    #include <stdio.h>
    
    #include <stdlib.h>

    int main(int argc, char *argv[])
    {
      FILE *fh;
      int i;
      if((fh = fopen("PRN:", "w")) != NULL) {
          for(i = 0; i<13; i++) {
             fprintf(fh, "Linia %d\n", i);
          }
          close(fh);
          printf("poszlo\n");
       }else{
          printf("nie ra dady\n");
       }
       system("PAUSE");
      return 0;
    }
  • Poziom 28  
    No, niestety u mnie nie połyka. Wypisuje "nie da rady". Nie może otworzyć pliku PRN: i fopen daje w wyniku null.
    Wic tkwi pewnie w samym PRN: ?
    Jak jeszcze mogę zrealizować?
  • Poziom 29  
    To może zacznijmy od tego: Jaką masz drukarkę?
  • Poziom 28  
    W zasadzie mam dwie. Obie to Lexmarki. Jedna to staruszek Z11, druga nie pamiętam (jestem aktualnie w pracy).
  • Specjalista techniki cyfrowej
    Nie wiem czy będzie to działać na drukarkach wyposażonych w port USB. Nie pamiętam jak to na Canonie testowałem, ale coś mi się zdaje że też w ten sposób. Przypuszczam, że może to być kwestia odpowiednich sterowników. Sterownik który zgłasza drukarkę jako pracującą wyłącznie w trybie graficznym raczej nie pozwoli na uruchomienie trybu tekstowego via PRN:

    Ten program sprawdziłem na HP LaserJet 4 Plus. Na pewno coś podobnego działało kiedyś mi na Epsonie LQ-550 (igłowa).

    Jeżeli masz drukarkę na porcie równoległym, spróbuj zapisu do odpowiedniego portu LPT (LPT1:, LPT2: itd.) Z tym że niekoniecznie musi to zadziałać, niektóre drukarki mogą wymagać jakiejś inicjalizacji. Igłowe Epsona drukują dane wysyłane na port domyślnie w trybie tekstowym, trylko trzeba uważać, żeby w ciągu znaczków nie pojawiła się jakaś sekwencja kodów sterujących (odsyłam do dokumentacji języka interpretowanego przez daną drukarkę).

    Zerknij w panelu sterowania we właściwości drukarki, w karcie Porty powinna być podana nazwa urządzenia logicznego przez które można odwoływać się do drukarki. Tylko nie wiem czy to coś da, prawdopodobnie należy znać składnię parametrów (podawaną w tym wypadku chyba jako ścieżka dostępu, a nie tylko nazwa urządzenia), próbowałem przed chwilą w ten sposób uruchomić mój program na urządzeniu logicznym PDFCreator:, niestety bezskutecznie, wyświetla że plik został otworzony, ale sama aplikacja (GUI PDFCreatora) się nie uruchamia.

    W ostateczności pozostaje jeszcze GDI. Niestety nie wyglada to zbyt ciekawie, chociaż i skrajnie skomplikowane też nie jest.
  • Poziom 29  
    A może trochę zmienić założenia i nie drukować na bieżąco tylko np. co stronę? Zbierać wyniki a jak się pełna strona uzbiera to wtedy print...?
  • Poziom 28  
    Aha, jest jeszcze ciekawiej. W domu przetestowałem oba kody i żaden nie dasje błędów, ale i nie drukuje. System nie przyjmuje mi zadania do drukowania. Teraz już zgłupiałem. Z linii poleceń po wpisaniu "print text.txt" - potwierdza komunikatem, ale nadal nic. Mam nawet userporta, ale uruchomienie nie pomogło.
    Jak podejść do tematu?
    Już nie upieram się na tryb wierszowy...
    :-)
    Teraz chciałbym chociaż stronka po stronce. Jak będzie na gwałt potrzebny tryb wierszowy, to pojawiła mi się drukarka igłowa na horyzoncie.
  • Poziom 29  
    Jak stronka po stronce to wal wszystko do pliku tekstowego a potem po uzbieraniu się odpowiedniej liczby linii drukuj plik za pomocą wywoływania chociażby notatnika z opcją /print ;-) Chyba że takie rozwiązanie nie wchodzi w grę.