Drukowanie przy użyciu systemowego drivera

0

Witam,

Mam taki temat, w którym potrzebuję wydrukować coś przy użyciu drukarki zainstalowanej w systemie. Z tego co rozeznałem, to nie ma jakieś możliwości drukowania multiplatformowego, a więc jestem skazany pod windowsem na WinApi - jeżeli się mylę proszę o poprawkę.

W związku z czym, mam pytanie. Mam drukarkę zwyczajną biurową oraz jedną paragonową obsługującą protokół ESC/POS. Jeżeli chodzi o drukowanie przy użyciu drukarki paragonowej to jest możliwość wysyłania do niej danych przy użyciu funkcji z dokumentacji MSDN (LINK). Mnie jednak to rozwiązanie się nie podoba i chciałbym móc drukować przez systemowy spooler.

To udało się zrobić poprzez funkcję TextOut na uchwycie drukarki. Chciałbym jednak móc sterować rozmiarem czcionki, w związku z czym mam pytania:

  • jak poprawnie ustawić czcionkę przy użyciu funkcji CreateFont?
  • czy da się sterować wysokością (bez zmiany szerokości czcionki)?
  • czy da się sterować szerokością (bez zmiany wysokości czcionki)?

Myślę, że osoby, które miały do czynienia z WinApi, niekoniecznie z samym drukowaniem będą w stanie coś mi podpowiedzieć.

Pozdrawiam,
wyebani

1

W roku 2020 używasz gołego WinApi w C++?
Nie masz tam żadnego frameworka GUI???

0
AnyKtokolwiek napisał(a):

W roku 2020 używasz gołego WinApi w C++?
Nie masz tam żadnego frameworka GUI???

No niestety, to nie jest tak na prawdę aplikacja z GUI ale chcę zrealizować funkcję drukowania pod Windowsem. Mam dane do wydruku w postaci listy stringów zawierającej kolejne linie do wydruku. Chciałbym jednak móc zmieniać wygląd czcionki, np.

  • pierwsza linia (czcionka Courier wysokość 10, szerokość 10)
  • druga linia (czcionka Courier wysokość 20, szerokość 10)
  • trzecia linia (czcionka Courier wysokość, 10, szerokość 20)

Jeżeli jest jakiś inny framework umożliwiający drukowanie (poza Qt) to daj znać proszę, na pewno się zaznajomię.
Dzięki za odpowiedź.

2
wyebani napisał(a):

Z tego co rozeznałem, to nie ma jakieś możliwości drukowania multiplatformowego, a więc jestem skazany pod windowsem na WinApi - jeżeli się mylę proszę o poprawkę.

Oczywiście, że jest. Np w Qt:
https://doc.qt.io/qt-5/qtprintsupport-index.html

0
MarekR22 napisał(a):
wyebani napisał(a):

Z tego co rozeznałem, to nie ma jakieś możliwości drukowania multiplatformowego, a więc jestem skazany pod windowsem na WinApi - jeżeli się mylę proszę o poprawkę.

Oczywiście, że jest. Np w Qt:
https://doc.qt.io/qt-5/qtprintsupport-index.html

Qt nie wchodzi w grę niestety.

0

czy da się sterować wysokością (bez zmiany szerokości czcionki)?
czy da się sterować szerokością (bez zmiany wysokości czcionki)?

No a parametry cHeight i cWidth funkcji CreateFont, nie działają?

0
0x666 napisał(a):

czy da się sterować wysokością (bez zmiany szerokości czcionki)?
czy da się sterować szerokością (bez zmiany wysokości czcionki)?

No a parametry cHeight i cWidth funkcji CreateFont, nie działają?

Działają, jednak nie do końca tak jak myślałem, że działają. Jednak po zastosowaniu funkcji MulDiv działa tak jak myślałem, że będzie działać ;)

1

Jeśli chcesz to obsługiwać za pomocą WINAPI, to powinieneś spojrzeć na te funkcje:
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setwindowextex
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setviewportextex
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setviewportorgex
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setwindoworgex

Zwróć uwagę, że te funkcje zadziałają, kiedy ustawisz odpowiedni tryb za pomocą tej funkcji:
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setmapmode

Generalnie pomysł na drukowanie w Windowsie był taki, że nie trzeba skalować czcionki i każdego elementu wydruku indywidualnie, tylko rysujesz sobie na ekranie (w oknie) to co chcesz za pomocą zwykłych funkcji rysujących, a potem zamiast kontekstu okna dajesz kontekst drukarki (pobrany np. przez tę funkcję):
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms646940(v=vs.85)

I wszystko się ładnie drukuje, tylko oczywiście jest za małe na wydruku. I teraz używając tych czterech funkcji ustawiasz globalne skalowanie i przesunięcie początku układu. To jest trochę "pomigane", musisz poeksperymentować, ale działa.

Musisz jeszcze użyć czterech funkcji pomocniczych (początek drukowania, początek strony, koniec strony i koniec drukowania):
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-startdocw
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-startpage
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-endpage
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-enddoc

Kontekst zwracany przez PrintDlg trzeba zwolnić.

Ale jest jeszcze droga przez Postscript. Jeśli masz drukarkę postscriptową, albo możesz zainstalować jakąś wirtualną drukarkę postscriptową (może konwertująca w locie do pdf-a, musisz poszukać, na pewno znajdziesz), to wtedy tworzysz zwykły plik tekstowy w PostScripcie i go wysyłasz do drukarki. W ostateczności instalujesz Ghostscripta, do niego wysyłasz PostScript, a z niego drukujesz na czym chcesz.
PostScript jest niezależny od sprzętu, więc jak zadasz wielkość czcionki w punktach, to taka będzie wielkość niezależnie na czym to wydrukujesz.
Z tego co napisałeś (pierwsza linia, druga linia, itd.), to program w PostScripcie będzie prostszy niż w Windowsie :-).
Gdybyś się zdecydował na to rozwiązanie to napisz, powiem Ci więcej jak się za to zabrać.

Możesz jeszcze zapisać te dane, potem localhost, php i biblioteka do tworzenia pdf-a, albo dane zapakować do przeglądarki i wydruk z przeglądarki?

0

Dzięki za odpowiedzi - udało się po zmieniać szerokość/wysokość czcionki poprzez funkcję MulDiv.

1 użytkowników online, w tym zalogowanych: 0, gości: 1