Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/teraprn.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10806 - (show annotations) (download) (as text)
Sun Jul 23 07:07:41 2023 UTC (10 months, 2 weeks ago) by zmatsuo
File MIME type: text/x-c++src
File size: 18694 byte(s)
文字を拡大縮小して描画できるようにした

- 拡大縮小して描画できるようにした
  - 2cell幅の文字を1cell幅に縮小して描画
  - 1cell幅の文字を2cell幅に拡大して描画,等
- フォントプロパティーページに設定を追加
  - "Drawing resized font to fit cell width" checkbox
- compat_win.cpp に TransparentBlt() (msimg32.dll) を追加
- ヘルプ追加(enはjaのコピー)
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2007- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /* TERATERM.EXE, Printing routines */
31 #include "teraterm.h"
32 #include "tttypes.h"
33 #include <commdlg.h>
34 #include <stdio.h>
35 #define _CRTDBG_MAP_ALLOC
36 #include <stdlib.h>
37 #include <crtdbg.h>
38
39 #include "ttwinman.h"
40 #include "commlib.h"
41 #include "ttcommon.h"
42 #include "ttlib.h"
43 #include "codeconv.h"
44 #include "vtdisp.h"
45
46 #include "tt_res.h"
47 #include "tmfc.h"
48 #include "prnabort.h"
49
50 #include "teraprn.h"
51
52 #ifdef _DEBUG
53 #if defined(_MSC_VER)
54 #define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
55 #endif
56 #endif
57
58 static HDC PrintDC;
59 static HFONT PrnFont[AttrFontMask+1];
60 static int PrnFW, PrnFH;
61 static RECT Margin;
62 static COLORREF White, Black;
63 static int PrnX, PrnY;
64 static TCharAttr PrnAttr;
65
66 static BOOL Printing = FALSE;
67 static BOOL PrintAbortFlag = FALSE;
68
69 static CPrnAbortDlg *PrnAbortDlg;
70 static HWND HPrnAbortDlg;
71
72 static void PrnSetAttr(TCharAttr Attr);
73
74 /* Print Abortion Call Back Function */
75 static BOOL CALLBACK PrnAbortProc(HDC PDC, int Code)
76 {
77 MSG m;
78
79 while ((! PrintAbortFlag) && PeekMessage(&m, 0,0,0, PM_REMOVE))
80 if ((HPrnAbortDlg==NULL) || (! IsDialogMessage(HPrnAbortDlg, &m))) {
81 TranslateMessage(&m);
82 DispatchMessage(&m);
83 }
84
85 if (PrintAbortFlag) {
86 HPrnAbortDlg = NULL;
87 PrnAbortDlg = NULL;
88 return FALSE;
89 }
90 else {
91 return TRUE;
92 }
93 }
94
95 static UINT_PTR CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
96 {
97 return 0;
98 }
99
100 HDC PrnBox(HWND HWin, PBOOL Sel)
101 {
102 /* initialize PrnDlg record */
103 PRINTDLGW PrnDlg = {};
104 PrnDlg.lStructSize = sizeof(PrnDlg);
105 PrnDlg.hwndOwner = HWin;
106 PrnDlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_SHOWHELP | PD_ENABLEPRINTHOOK;
107 if (! *Sel) {
108 PrnDlg.Flags = PrnDlg.Flags | PD_NOSELECTION; /* when there is nothing select, gray out the "Selection" radio button */
109 } else {
110 PrnDlg.Flags = PrnDlg.Flags | PD_SELECTION; /* when there is something select, select the "Selection" radio button by default */
111 }
112 PrnDlg.nCopies = 1;
113 /*
114 * Windows NT�n���������A�����_�C�A���O���w���v�{�^�����\�����������A
115 * �v���V�[�W�����t�b�N�����B
116 */
117 PrnDlg.lpfnPrintHook = PrintHookProc;
118
119 /* 'Print' dialog box */
120 if (! PrintDlgW(&PrnDlg)) {
121 return NULL; /* if 'Cancel' button clicked, exit */
122 }
123 if (PrnDlg.hDC == NULL) {
124 return NULL;
125 }
126 *Sel = (PrnDlg.Flags & PD_SELECTION) != 0;
127 return PrnDlg.hDC;
128 }
129
130 BOOL PrnStart(LPSTR DocumentName)
131 {
132 DOCINFOA Doc;
133 char DocName[50];
134 HWND hParent;
135
136 Printing = FALSE;
137 PrintAbortFlag = FALSE;
138
139 PrnAbortDlg = new CPrnAbortDlg();
140 if (PrnAbortDlg==NULL) {
141 return FALSE;
142 }
143 if (ActiveWin==IdVT) {
144 hParent = HVTWin;
145 }
146 else {
147 hParent = HTEKWin;
148 }
149 PrnAbortDlg->Create(hInst,hParent,&PrintAbortFlag,&ts);
150 HPrnAbortDlg = PrnAbortDlg->GetSafeHwnd();
151
152 SetAbortProc(PrintDC,PrnAbortProc);
153
154 Doc.cbSize = sizeof(Doc);
155 strncpy_s(DocName,sizeof(DocName),DocumentName,_TRUNCATE);
156 Doc.lpszDocName = DocName;
157 Doc.lpszOutput = NULL;
158 Doc.lpszDatatype = NULL;
159 Doc.fwType = 0;
160 if (StartDocA(PrintDC, &Doc) > 0) {
161 Printing = TRUE;
162 }
163 else {
164 if (PrnAbortDlg != NULL) {
165 PrnAbortDlg->DestroyWindow();
166 PrnAbortDlg = NULL;
167 HPrnAbortDlg = NULL;
168 }
169 }
170 return Printing;
171 }
172
173 void PrnStop()
174 {
175 if (Printing) {
176 EndDoc(PrintDC);
177 DeleteDC(PrintDC);
178 Printing = FALSE;
179 }
180 if (PrnAbortDlg != NULL) {
181 PrnAbortDlg->DestroyWindow();
182 PrnAbortDlg = NULL;
183 HPrnAbortDlg = NULL;
184 }
185 }
186
187 int VTPrintInit(int PrnFlag)
188 // Initialize printing of VT window
189 // PrnFlag: specifies object to be printed
190 // = IdPrnScreen Current screen
191 // = IdPrnSelectedText Selected text
192 // = IdPrnScrollRegion Scroll region
193 // = IdPrnFile Spooled file (printer sequence)
194 // Return: print object ID specified by user
195 // = IdPrnCancel (user clicks "Cancel" button)
196 // = IdPrnScreen (user don't select "print selection" option)
197 // = IdPrnSelectedText (user selects "print selection")
198 // = IdPrnScrollRegion (always when PrnFlag=IdPrnScrollRegion)
199 // = IdPrnFile (always when PrnFlag=IdPrnFile)
200 {
201 BOOL Sel;
202 TEXTMETRIC Metrics;
203 POINT PPI, PPI2;
204 HDC DC;
205 TCharAttr TempAttr = DefCharAttr;
206 LOGFONTA Prnlf;
207
208 Sel = (PrnFlag & IdPrnSelectedText)!=0;
209 PrintDC = PrnBox(HVTWin,&Sel);
210 if (PrintDC == NULL) {
211 return (IdPrnCancel);
212 }
213
214 /* start printing */
215 if (! PrnStart(ts.Title)) {
216 return (IdPrnCancel);
217 }
218
219 /* initialization */
220 StartPage(PrintDC);
221
222 /* pixels per inch */
223 if ((ts.VTPPI.x>0) && (ts.VTPPI.y>0)) {
224 PPI = ts.VTPPI;
225 }
226 else {
227 PPI.x = GetDeviceCaps(PrintDC,LOGPIXELSX);
228 PPI.y = GetDeviceCaps(PrintDC,LOGPIXELSY);
229 }
230
231 /* left margin */
232 Margin.left = (int)((float)ts.PrnMargin[0] / 100.0 * (float)PPI.x);
233 /* right margin */
234 Margin.right = GetDeviceCaps(PrintDC,HORZRES) -
235 (int)((float)ts.PrnMargin[1] / 100.0 * (float)PPI.x);
236 /* top margin */
237 Margin.top = (int)((float)ts.PrnMargin[2] / 100.0 * (float)PPI.y);
238 /* bottom margin */
239 Margin.bottom = GetDeviceCaps(PrintDC,VERTRES) -
240 (int)((float)ts.PrnMargin[3] / 100.0 * (float)PPI.y);
241
242 /* create test font */
243 memset(&Prnlf, 0, sizeof(Prnlf));
244
245 if (ts.PrnFont[0]==0) {
246 Prnlf.lfHeight = ts.VTFontSize.y;
247 Prnlf.lfWidth = ts.VTFontSize.x;
248 Prnlf.lfCharSet = ts.VTFontCharSet;
249 strncpy_s(Prnlf.lfFaceName, sizeof(Prnlf.lfFaceName), ts.VTFont, _TRUNCATE);
250 }
251 else {
252 Prnlf.lfHeight = ts.PrnFontSize.y;
253 Prnlf.lfWidth = ts.PrnFontSize.x;
254 Prnlf.lfCharSet = ts.PrnFontCharSet;
255 strncpy_s(Prnlf.lfFaceName, sizeof(Prnlf.lfFaceName), ts.PrnFont, _TRUNCATE);
256 }
257 Prnlf.lfWeight = FW_NORMAL;
258 Prnlf.lfItalic = 0;
259 Prnlf.lfUnderline = 0;
260 Prnlf.lfStrikeOut = 0;
261 Prnlf.lfOutPrecision = OUT_CHARACTER_PRECIS;
262 Prnlf.lfClipPrecision = CLIP_CHARACTER_PRECIS;
263 Prnlf.lfQuality = DEFAULT_QUALITY;
264 Prnlf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
265
266 PrnFont[0] = CreateFontIndirectA(&Prnlf);
267
268 DC = GetDC(HVTWin);
269 SelectObject(DC, PrnFont[0]);
270 GetTextMetrics(DC, &Metrics);
271 PPI2.x = GetDeviceCaps(DC,LOGPIXELSX);
272 PPI2.y = GetDeviceCaps(DC,LOGPIXELSY);
273 ReleaseDC(HVTWin,DC);
274 DeleteObject(PrnFont[0]); /* Delete test font */
275
276 /* Adjust font size */
277 Prnlf.lfHeight = (int)((float)Metrics.tmHeight * (float)PPI.y / (float)PPI2.y);
278 Prnlf.lfWidth = (int)((float)Metrics.tmAveCharWidth * (float)PPI.x / (float)PPI2.x);
279
280 /* Create New Fonts */
281
282 /* Normal Font */
283 Prnlf.lfWeight = FW_NORMAL;
284 Prnlf.lfUnderline = 0;
285 PrnFont[0] = CreateFontIndirectA(&Prnlf);
286 SelectObject(PrintDC,PrnFont[0]);
287 GetTextMetrics(PrintDC, &Metrics);
288 PrnFW = Metrics.tmAveCharWidth;
289 PrnFH = Metrics.tmHeight;
290 /* Under line */
291 Prnlf.lfUnderline = 1;
292 PrnFont[AttrUnder] = CreateFontIndirectA(&Prnlf);
293
294 if (ts.FontFlag & FF_BOLD) {
295 /* Bold */
296 Prnlf.lfUnderline = 0;
297 Prnlf.lfWeight = FW_BOLD;
298 PrnFont[AttrBold] = CreateFontIndirectA(&Prnlf);
299 /* Bold + Underline */
300 Prnlf.lfUnderline = 1;
301 PrnFont[AttrBold | AttrUnder] = CreateFontIndirectA(&Prnlf);
302 }
303 else {
304 PrnFont[AttrBold] = PrnFont[AttrDefault];
305 PrnFont[AttrBold | AttrUnder] = PrnFont[AttrUnder];
306 }
307 /* Special font */
308 Prnlf.lfWeight = FW_NORMAL;
309 Prnlf.lfUnderline = 0;
310 Prnlf.lfWidth = PrnFW; /* adjust width */
311 Prnlf.lfHeight = PrnFH;
312 Prnlf.lfCharSet = SYMBOL_CHARSET;
313
314 strncpy_s(Prnlf.lfFaceName, sizeof(Prnlf.lfFaceName),"Tera Special", _TRUNCATE);
315 PrnFont[AttrSpecial] = CreateFontIndirectA(&Prnlf);
316 PrnFont[AttrSpecial | AttrBold] = PrnFont[AttrSpecial];
317 PrnFont[AttrSpecial | AttrUnder] = PrnFont[AttrSpecial];
318 PrnFont[AttrSpecial | AttrBold | AttrUnder] = PrnFont[AttrSpecial];
319
320 Black = RGB(0,0,0);
321 White = RGB(255,255,255);
322 PrnSetAttr(TempAttr);
323
324 PrnY = Margin.top;
325 PrnX = Margin.left;
326
327 if (PrnFlag == IdPrnScrollRegion) {
328 return (IdPrnScrollRegion);
329 }
330 if (PrnFlag == IdPrnFile) {
331 return (IdPrnFile);
332 }
333 if (Sel) {
334 return (IdPrnSelectedText);
335 }
336 else {
337 return (IdPrnScreen);
338 }
339 }
340
341 static void PrnSetAttr(TCharAttr Attr)
342 // Set text attribute of printing
343 //
344 {
345 PrnAttr = Attr;
346 SelectObject(PrintDC, PrnFont[Attr.Attr & AttrFontMask]);
347
348 if ((Attr.Attr & AttrReverse) != 0) {
349 SetTextColor(PrintDC,White);
350 SetBkColor( PrintDC,Black);
351 }
352 else {
353 SetTextColor(PrintDC,Black);
354 SetBkColor( PrintDC,White);
355 }
356 }
357
358 void PrnSetupDC(TCharAttr Attr, BOOL reverse)
359 {
360 (void)reverse;
361 PrnSetAttr(Attr);
362 }
363
364 /**
365 * Print out text
366 * Buff: points text buffer
367 * Count: number of characters to be printed
368 */
369 void PrnOutTextA(const char *StrA, const char *WidthInfo, int Count, void *data)
370 {
371 if (PrnX+PrnFW > Margin.right) {
372 /* new line */
373 PrnX = Margin.left;
374 PrnY = PrnY + PrnFH;
375 }
376 if (PrnY+PrnFH > Margin.bottom) {
377 /* next page */
378 EndPage(PrintDC);
379 StartPage(PrintDC);
380 PrnSetAttr(PrnAttr);
381 PrnY = Margin.top;
382 }
383
384 DrawStrA(PrintDC, NULL, StrA, WidthInfo, Count, PrnFW, PrnFH, PrnY, &PrnX);
385 }
386
387 void PrnOutTextW(const wchar_t *StrW, const char *cells, int len, void *data)
388 {
389 if (PrnX+PrnFW > Margin.right) {
390 /* new line */
391 PrnX = Margin.left;
392 PrnY = PrnY + PrnFH;
393 }
394 if (PrnY+PrnFH > Margin.bottom) {
395 /* next page */
396 EndPage(PrintDC);
397 StartPage(PrintDC);
398 PrnSetAttr(PrnAttr);
399 PrnY = Margin.top;
400 }
401
402 DrawStrW(PrintDC, NULL, StrW, cells, len, PrnFW, PrnFH, PrnY, &PrnX);
403 }
404
405 void PrnNewLine()
406 // Moves to the next line in printing
407 {
408 PrnX = Margin.left;
409 PrnY = PrnY + PrnFH;
410 }
411
412 void VTPrintEnd()
413 {
414 int i, j;
415
416 EndPage(PrintDC);
417
418 for (i = 0 ; i <= AttrFontMask ; i++) {
419 for (j = i+1 ; j <= AttrFontMask ; j++) {
420 if (PrnFont[j]==PrnFont[i]) {
421 PrnFont[j] = NULL;
422 }
423 }
424 if (PrnFont[i] != NULL) {
425 DeleteObject(PrnFont[i]);
426 }
427 }
428
429 PrnStop();
430 return;
431 }
432
433 /* pass-thru printing */
434 typedef struct PrintFileTag {
435 wchar_t *PrnFName;
436 HANDLE HPrnFile;
437 unsigned int PrnBuff[TermWidthMax*2];
438 int PrnBuffCount;
439 void (*FinishCallback)(PrintFile *handle);
440 } PrintFile;
441
442 /* printer emulation routines */
443 PrintFile *OpenPrnFile(void)
444 {
445 PrintFile *p = (PrintFile *)calloc(sizeof(PrintFile),1 );
446 if (p == NULL) {
447 return NULL;
448 }
449
450 KillTimer(HVTWin, IdPrnStartTimer);
451
452 wchar_t TempPath[MAX_PATH];
453 GetTempPathW(_countof(TempPath), TempPath);
454 wchar_t Temp[MAX_PATH];
455 if (GetTempFileNameW(TempPath, L"tmp", 0, Temp) == 0) {
456 free(p);
457 return NULL;
458 }
459 p->PrnFName = _wcsdup(Temp);
460
461 HANDLE h = CreateFileW(p->PrnFName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
462 if (h == INVALID_HANDLE_VALUE) {
463 free(p);
464 return NULL;
465 }
466 SetFilePointer(h, 0, NULL, FILE_END);
467 p->HPrnFile = h;
468
469 return p;
470 }
471
472 static void DeletePrintFile(PrintFile *handle)
473 {
474 if (handle->PrnFName == NULL) {
475 return;
476 }
477 DeleteFileW(handle->PrnFName);
478 free(handle->PrnFName);
479 handle->PrnFName = NULL;
480 }
481
482 void PrnFinish(PrintFile *handle)
483 {
484 DeletePrintFile(handle);
485 free(handle);
486 }
487
488 static void PrnOutText(const char *StrA, int Count, void *data)
489 {
490 // ����������������
491 // MBCS�������A1byte=1cell, 2byte=2cell
492 char *WidthInfo = (char *)malloc(Count);
493 char *w = WidthInfo;
494 BYTE *s = (BYTE*)StrA;
495 for (int i = 0; i < Count; i++) {
496 BYTE b = *s++;
497 if (__ismbblead(b, CP_ACP)) {
498 // 2byte����
499 *w++ = 2;
500 *w++ = 0;
501 s++;
502 i++;
503 }
504 else {
505 // 1byte����
506 *w++ = 1;
507 }
508 }
509
510 DrawStrA(PrintDC, NULL, StrA, WidthInfo, Count, PrnFW, PrnFH, PrnY, &PrnX);
511
512 free(WidthInfo);
513 }
514
515 /**
516 * �����p���������������t�@�C��������������
517 */
518 static void PrintFile_(PrintFile *handle)
519 {
520 if (VTPrintInit(IdPrnFile)==IdPrnFile) {
521 HANDLE HPrnFile = CreateFileW(handle->PrnFName,
522 GENERIC_READ, FILE_SHARE_READ, NULL,
523 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
524
525 if (HPrnFile != INVALID_HANDLE_VALUE) {
526 char BuffA[TermWidthMax];
527 size_t len_a;
528 wchar_t BuffW[TermWidthMax];
529 size_t len_w;
530 BOOL CRFlag = FALSE;
531 int c;
532 unsigned int u32;
533 do {
534 len_a = 0;
535 len_w = 0;
536 do {
537 DWORD NumberOfBytesRead;
538 BOOL r = ReadFile(HPrnFile, &u32, sizeof(u32), &NumberOfBytesRead, NULL);
539 if (r == TRUE && NumberOfBytesRead != 0) {
540 // �����p��
541 c = 1;
542 }
543 else {
544 c = 0;
545 }
546 if (c == 1) {
547 switch (u32) {
548 case LF:
549 CRFlag = ! CRFlag;
550 break;
551 case FF:
552 case CR:
553 CRFlag = TRUE;
554 break;
555 #if 0
556 case HT:
557 memset(&(Buff[i]),0x20,8);
558 i = i + 8;
559 CRFlag = FALSE;
560 break;
561 #endif
562 default:
563 if (u32 >= 0x20) {
564 int codepage = CP_ACP; // �����p�R�[�h�y�[�W
565 size_t out_len = UTF32ToUTF16(u32, &BuffW[len_w], _countof(BuffW) - len_w);
566 len_w += out_len;
567 out_len = UTF32ToMBCP(u32, codepage, &BuffA[len_a], _countof(BuffA) - len_a);
568 len_a += out_len;
569 }
570 CRFlag = FALSE;
571 break;
572 }
573 }
574 if (len_w >= (_countof(BuffW)-7)) {
575 CRFlag=TRUE;
576 }
577 } while ((c>0) && (! CRFlag));
578 if (len_a >0) {
579 PrnOutText(BuffA, len_a, NULL);
580 //PrnOutTextW(BuffW, NULL, len_w, NULL);
581 }
582 if (CRFlag) {
583 PrnX = Margin.left;
584 if ((u32==FF) && (ts.PrnConvFF==0)) { // new page
585 PrnY = Margin.bottom;
586 }
587 else { // new line
588 PrnY = PrnY + PrnFH;
589 }
590 }
591 CRFlag = (u32==CR);
592 } while (c>0);
593 CloseHandle(HPrnFile);
594 }
595 HPrnFile = INVALID_HANDLE_VALUE;
596 VTPrintEnd();
597 }
598 handle->FinishCallback(handle);
599 }
600
601 static void PrintFileDirect(PrintFile *handle)
602 {
603 HWND hParent;
604
605 PrnAbortDlg = new CPrnAbortDlg();
606 if (PrnAbortDlg==NULL) {
607 DeletePrintFile(handle);
608 return;
609 }
610 if (ActiveWin==IdVT) {
611 hParent = HVTWin;
612 }
613 else {
614 hParent = HTEKWin;
615 }
616 PrnAbortDlg->Create(hInst,hParent,&PrintAbortFlag,&ts);
617 HPrnAbortDlg = PrnAbortDlg->GetSafeHwnd();
618
619 handle->HPrnFile = CreateFileW(handle->PrnFName,
620 GENERIC_READ, FILE_SHARE_READ, NULL,
621 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
622 PrintAbortFlag = (handle->HPrnFile == INVALID_HANDLE_VALUE) || ! PrnOpen(ts.PrnDev);
623 handle->PrnBuffCount = 0;
624 SetTimer(HVTWin,IdPrnProcTimer,0,NULL);
625 }
626
627 void PrnFileDirectProc(PrintFile *handle)
628 {
629 HANDLE HPrnFile = handle->HPrnFile;
630 if (HPrnFile==INVALID_HANDLE_VALUE) {
631 return;
632 }
633 if (PrintAbortFlag) {
634 HPrnAbortDlg = NULL;
635 PrnAbortDlg = NULL;
636 PrnCancel();
637 }
638 if (!PrintAbortFlag && (HPrnFile != INVALID_HANDLE_VALUE)) {
639 int c;
640 do {
641 if (handle->PrnBuffCount==0) {
642 handle->PrnBuffCount = 0;
643 DWORD NumberOfBytesRead;
644 BOOL r = ReadFile(HPrnFile, handle->PrnBuff, sizeof(handle->PrnBuff[0]), &NumberOfBytesRead, NULL);
645 if (r) {
646 handle->PrnBuffCount = NumberOfBytesRead;
647 }
648 }
649
650 if (handle->PrnBuffCount != 0) {
651 // UTF-32
652 unsigned int u32 = handle->PrnBuff[0];
653 int codepage = CP_ACP; // �����p�R�[�h�y�[�W
654 char str[5];
655 size_t out_len = UTF32ToMBCP(u32, codepage, str, _countof(str));
656 c = PrnWrite(str, out_len);
657 if (c==0) {
658 SetTimer(HVTWin,IdPrnProcTimer,10,NULL);
659 return;
660 }
661 handle->PrnBuffCount = 0;
662 }
663 else {
664 c = 0;
665 }
666 } while (c>0);
667 }
668 PrnClose();
669
670 if (PrnAbortDlg!=NULL) {
671 PrnAbortDlg->DestroyWindow();
672 PrnAbortDlg = NULL;
673 HPrnAbortDlg = NULL;
674 }
675
676 handle->FinishCallback(handle);
677 }
678
679 /**
680 * �^�C�}�[�������o���A�������J�n����
681 * ClosePrnFile() �� SetTimer(IdPrnStartTimer) ���g���K
682 */
683 void PrnFileStart(PrintFile *handle)
684 {
685 if (handle->HPrnFile != INVALID_HANDLE_VALUE) {
686 return;
687 }
688 if (handle->PrnFName == NULL) {
689 return;
690 }
691 if (ts.PrnDev[0]!=0) {
692 PrintFileDirect(handle); // send file directry to printer port
693 }
694 else { // print file by using Windows API
695 PrintFile_(handle);
696 }
697 }
698
699 /**
700 * �v�����g�p�t�@�C���������������I��
701 * �v�����g���J�n�^�C�}�[���Z�b�g����
702 */
703 void ClosePrnFile(PrintFile *handle, void (*finish_callback)(PrintFile *handle))
704 {
705 PrintFile *p = handle;
706 p->PrnBuffCount = 0;
707 p->FinishCallback = finish_callback;
708 if (p->HPrnFile != INVALID_HANDLE_VALUE) {
709 CloseHandle(p->HPrnFile);
710 p->HPrnFile = INVALID_HANDLE_VALUE;
711 }
712 SetTimer(HVTWin,IdPrnStartTimer,ts.PassThruDelay*1000,NULL);
713 }
714
715 /**
716 * (b,Write) =
717 * (0,FALSE): clear buffer
718 * (0,TRUE): write buffer to file
719 * (b,FALSE): put b in buff
720 * (b,TRUE): put b in buff and
721 * write buffer to file
722 */
723 void WriteToPrnFileUTF32(PrintFile *handle, unsigned int u32, BOOL Write)
724 {
725 PrintFile *p = handle;
726 if ((u32 > 0) && p->PrnBuffCount < _countof(p->PrnBuff)) {
727 p->PrnBuff[p->PrnBuffCount++] = u32;
728 }
729
730 if (Write) {
731 DWORD NumberOfBytesWritten;
732 WriteFile(p->HPrnFile, p->PrnBuff, sizeof(p->PrnBuff[0]) * p->PrnBuffCount, &NumberOfBytesWritten, NULL);
733 p->PrnBuffCount = 0;
734 }
735 if ((u32 == 0) && !Write) {
736 p->PrnBuffCount = 0;
737 }
738 }
739
740 void WriteToPrnFile(PrintFile *handle, BYTE b, BOOL Write)
741 {
742 WriteToPrnFileUTF32(handle, b, Write);
743 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26