Добрый день, всем! Может кто подскажет, как работать с этими функциями... invoke SaveDC,hdcPrint invoke SetMapMode, hdcPrint, MM_ISOTROPIC invoke SetWindowExtEx, hdcPrint, 1000, 1000, NULL invoke SetViewportExtEx, hdcPrint, 800, -600, NULL invoke SetViewportOrgEx, hdcPrint, 800 , 600, NULL это функции которые принимают участие в программировании принтера... тект печатаю, кружочки печатаю, прямоугольнички - криво, но печатаю, а вот картинки - не получается... с пом. BitBlt на монитор вывожу, а на принтер не получается...
Можно также пользовать MM_TEXT. Тогда на всех форматах бумаги картинки будут равного размера + отпадёт необходимость в SetWindowExtEx и SetViewportExtEx. А как вы вызываете BitBlt? Раз рисуются кружочки/квадратики, значит "на выходе" с DC проблем нет. Проблемы, вестимо, с тем DC, откуда вы копируете.
вот мой корявенький исходник... Код (Text): .386 .model flat, stdcall option casemap:none WinMain proto :DWORD, :DWORD, :DWORD, :DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\comdlg32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\comdlg32.lib RGB macro red,green,blue xor eax,eax mov ah,blue shl eax,8 mov ah,green mov al,red endm .const IDB_MAIN equ 555 IDC_EDIT equ 3000 IDC_BUTTON equ 3001 IDC_EXIT equ 3002 IDM_OPEN equ 1 IDM_SAVE equ 2 IDM_EXIT equ 3 IDM_WINBLT equ 4 MAXSIZE equ 260 MEMSIZE equ 65535 EditID equ 1 EditID2 equ 2 EditID3 equ 3 EditID4 equ 4 EditID5 equ 5 EditID6 equ 6 EditID7 equ 7 EditID8 equ 8 EditID9 equ 9 EditIDa equ 10 EditIDb equ 11 EditIDc equ 12 EditIDd equ 13 EditIDe equ 14 EditIDf equ 15 .data ClassName db "DLGCLASS",0 MenuName db "MyMenu", 0 EditClass db "edit", 0 DlgName db "MyDialog",0 AppName db "Приём выдача гарантийного товара",0 FontName db "script",0 DocName db "Facked Print!",0 PrinterName db "\\KASSA\HP Photosmart 8000 Series",0 HelloPrinter db "Hello, Printer!",0 Num db "запись №",0 NameClient db "ФИО клиента",0 BuyDate db "дата покупки",0 GoingDate db "дата отправки на СЦ",0 DateToday db "дата на момент приёма",0 Variety db "наименование",0 Model db "модель",0 SerialNum db "серийный номер",0 Diagnosis db "диагноз",0 Equipment db "комплектация",0 State db "состояние",0 MobilePhoneNum db "телефон моб.",0 HomePhone db "телефон дом.",0 Address db "адрес",0 WarrantyPeriod db "срок гарант. обслуживания",0 ofn OPENFILENAME <> docinf DOCINFO <> FilterString db "All Files",0,"*.*",0 db "Text Files",0,"*.txt",0,0 buffer db MAXSIZE dup(0) .data? hInstance HINSTANCE ? CommandLine LPSTR ? hFile HANDLE ? hMemory DWORD ? pMemory DWORD ? tempMemory DWORD ? SizeReadWrite DWORD ? temp DWORD ? hBitmap dd ? hwndEdit HWND ? hwndEdit2 HWND ? hwndEdit3 HWND ? hwndEdit4 HWND ? hwndEdit5 HWND ? hwndEdit6 HWND ? hwndEdit7 HWND ? hwndEdit8 HWND ? hwndEdit9 HWND ? hwndEdita HWND ? hwndEditb HWND ? hwndEditc HWND ? hwndEditd HWND ? hwndEdite HWND ? hwndEditf HWND ? hdcPrint HDC ? cxClient DWORD ? cyClient DWORD ? xx DWORD ? yy DWORD ? yyy DWORD ? .code start: invoke GetModuleHandle,NULL mov hInstance,eax invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT invoke ExitProcess, eax WinMain proc hInst: HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hDlg:HWND mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, DLGWINDOWEXTRA push hInst pop wc.hInstance mov wc.hbrBackground, COLOR_BTNFACE+1 mov wc.lpszMenuName, OFFSET MenuName mov wc.lpszClassName, OFFSET ClassName invoke LoadIcon, NULL, IDI_APPLICATION mov wc.hIcon, eax mov wc.hIconSm, eax invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax invoke RegisterClassEx, addr wc invoke CreateDialogParam, hInstance, ADDR DlgName, NULL, NULL, NULL mov hDlg,eax invoke GetDlgItem, hDlg, IDC_EDIT invoke SetFocus, eax invoke ShowWindow, hDlg, SW_SHOWNORMAL invoke UpdateWindow, hDlg .WHILE TRUE invoke GetMessage, ADDR msg, NULL, 0, 0 .BREAK .IF(!eax) invoke IsDialogMessage, hDlg, ADDR msg .if eax==FALSE invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endif .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL hfont:HFONT LOCAL hMemDC:HDC LOCAL rect:RECT .if uMsg==WM_CREATE invoke SetDlgItemText, hWnd, IDC_EDIT, ADDR AppName invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,40,525,17,hWnd, EditID,hInstance, NULL mov hwndEdit, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,80,525,17,hWnd, EditID2,hInstance, NULL mov hwndEdit2, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,120,525,17,hWnd, EditID3,hInstance, NULL mov hwndEdit3, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,160,525,17,hWnd, EditID4,hInstance, NULL mov hwndEdit4, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,200,525,17,hWnd, EditID5,hInstance, NULL mov hwndEdit5, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,240,525,17,hWnd, EditID6,hInstance, NULL mov hwndEdit6, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,280,525,17,hWnd, EditID7,hInstance, NULL mov hwndEdit7, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,320,525,17,hWnd, EditID8,hInstance, NULL mov hwndEdit8, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,360,525,17,hWnd, EditID9,hInstance, NULL mov hwndEdit9, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,400,525,17,hWnd, EditIDa,hInstance, NULL mov hwndEdita, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,440,525,17,hWnd, EditIDb,hInstance, NULL mov hwndEditb, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,480,525,17,hWnd, EditIDc,hInstance, NULL mov hwndEditc, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,520,525,17,hWnd, EditIDd,hInstance, NULL mov hwndEditd, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,560,525,17,hWnd, EditIDe,hInstance, NULL mov hwndEdite, eax invoke CreateWindowEx, NULL, ADDR EditClass, NULL, WS_VISIBLE or WS_CHILD or ES_LEFT,250,600,525,17,hWnd, EditIDf,hInstance, NULL mov hwndEditf, eax invoke SetFocus, hwndEdit mov ofn.lStructSize,SIZEOF ofn push hWnd pop ofn.hWndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile,MAXSIZE mov docinf.cbSize,SIZEOF docinf mov docinf.lpszDocName, OFFSET DocName mov docinf.lpszOutput, NULL invoke CreateDC, NULL, OFFSET PrinterName, NULL, NULL mov hdcPrint, eax .elseif uMsg==WM_DESTROY invoke PostQuitMessage, NULL .elseif uMsg==WM_SIZE mov eax, lParam mov cxClient, eax mov eax, wParam mov cyClient, eax .elseif uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax RGB 0,0,0 invoke SetTextColor,hdc,eax RGB 210,210,210 invoke SetBkColor,hdc,eax invoke TextOut,hdc,30,40,ADDR Num,SIZEOF Num-1 invoke TextOut,hdc,30,80,ADDR NameClient,SIZEOF NameClient-1 invoke TextOut,hdc,30,120,ADDR BuyDate,SIZEOF BuyDate-1 invoke TextOut,hdc,30,160,ADDR GoingDate,SIZEOF GoingDate-1 invoke TextOut,hdc,30,200,ADDR DateToday,SIZEOF DateToday-1 invoke TextOut,hdc,30,240,ADDR Variety,SIZEOF Variety-1 invoke TextOut,hdc,30,280,ADDR Model,SIZEOF Model-1 invoke TextOut,hdc,30,320,ADDR SerialNum,SIZEOF SerialNum-1 invoke TextOut,hdc,30,360,ADDR Diagnosis,SIZEOF Diagnosis-1 invoke TextOut,hdc,30,400,ADDR Equipment,SIZEOF Equipment-1 invoke TextOut,hdc,30,440,ADDR State,SIZEOF State-1 invoke TextOut,hdc,30,480,ADDR MobilePhoneNum,SIZEOF MobilePhoneNum-1 invoke TextOut,hdc,30,520,ADDR HomePhone,SIZEOF HomePhone-1 invoke TextOut,hdc,30,560,ADDR Address,SIZEOF Address-1 invoke TextOut,hdc,30,600,ADDR WarrantyPeriod,SIZEOF WarrantyPeriod-1 invoke EndPaint,hWnd, ADDR ps .elseif uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_OPEN .if (hdcPrint != NULL) invoke StartDoc, hdcPrint, offset docinf ;invoke StartPage,hdcPrint invoke EndPage, hdcPrint invoke SaveDC,hdcPrint invoke SetMapMode, hdcPrint, MM_ISOTROPIC invoke SetWindowExtEx, hdcPrint, 1000, 1000, NULL invoke SetViewportExtEx, hdcPrint, 800, -600, NULL invoke SetViewportOrgEx, hdcPrint, 800 , 600, NULL invoke SetTextAlign, hdcPrint, TA_BASELINE or TA_CENTER invoke TextOut, hdcPrint, 0, 0, offset HelloPrinter, 20 invoke LoadBitmap, hInstance, IDB_MAIN mov hBitmap, eax ;invoke CreateDC, NULL, OFFSET PrinterName, NULL, NULL ;mov hdcPrint, eax invoke CreateCompatibleDC, hdcPrint mov hMemDC, eax invoke SelectObject, hMemDC, hBitmap invoke BitBlt, hdc, 0, 0, 1000, 1000, hMemDC, 0, 0, SRCCOPY ;invoke Ellipse, hdcPrint, 0,0,500,500 invoke Rectangle, hdc,0, 0, 100, 100 invoke DeleteDC, hMemDC invoke RestoreDC, hdcPrint, -1 invoke EndDoc, hdcPrint invoke DeleteDC, hdcPrint .endif .elseif ax==IDM_WINBLT invoke LoadBitmap, hInstance, IDB_MAIN mov hBitmap,eax invoke GetDC, hWnd mov hdc, eax invoke CreateCompatibleDC, hdc mov hMemDC, eax invoke SelectObject, hMemDC, hBitmap invoke GetClientRect, hWnd, addr rect invoke BitBlt, hdc, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY invoke DeleteDC, hMemDC invoke EndPaint, hWnd, addr ps .elseif ax==IDM_SAVE mov ofn.Flags,OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetSaveFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR buffer,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFile,eax invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax mov tempMemory,eax invoke SendMessage,hwndEdit,WM_GETTEXT,MEMSIZE-1,pMemory ;invoke SendMessage,hwndEdit2,WM_GETTEXT,MEMSIZE-1,pMemory invoke WriteFile,hFile,tempMemory,eax,ADDR SizeReadWrite,NULL invoke CloseHandle,hFile invoke GlobalUnlock,pMemory invoke GlobalFree,hMemory .endif invoke SetFocus,hwndEdit .else invoke DestroyWindow, hWnd .endif .endif .else invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret .endif xor eax,eax ret WndProc endp end start
вызываю вот так invoke BitBlt, hdc, 0, 0, 1000, 1000, hMemDC, 0, 0, SRCCOPY, с функцией GetDevCaps не разобрался, поэтому от фонаря передаю координаты, возможно в этом и причина...
1) советую перенести в data? и поставить вместо dup(0) - dup(?). 2) Раскомментируйте. 3) Перенесите в конец, перед EndDoc. 4) А вот это сильно мне подозрительственно! Существует ли такой битмап вообще? Видимо, он просто не загружается. Да, кстати, после освобождения битмапного DC не забудьте освободить и сам битмап (юзая DeleteObject).
;invoke StartPage,hdcPrint если это раскоментить вместо одной страницы лезет две, и первая всегда пустая... на Epson С43 SX была одна страница, правда код копмилил VS C++ на лазерном HP - лезло две, masm32 компилил на струйном HP Photosmart 8000 - лезет тоже две по поводу IDB_MAIN волноватся не стоит, в файле ресурсов все прописано и проверено, все работает... если откомпилить прогу (хотя для этого нужен файл ресурсов) в меню есть пункт WINBLT, выбрав который таже картинка выскакивает в окне программы...
Тогда, вполне возможно, что грабли-таки в этих вот строчках: Код (Text): invoke SetMapMode, hdcPrint, MM_ISOTROPIC invoke SetWindowExtEx, hdcPrint, 1000, 1000, NULL invoke SetViewportExtEx, hdcPrint, 800, -600, NULL invoke SetViewportOrgEx, hdcPrint, 800 , 600, NULL И если скормить BitBlt ширину/высоту рисунка, большую чем вью-порт, то просто ничего не выведетсо... пробуй сначала 100х100. [+]: Код есть, только, увы, на Делфях %)
хотя... может быть их и лезит две потому что не верно заданы вот эти самые экстенты и логические единицы...
перенёс EndPage в конец, и раскоментил StartPage, начало печатать одну страничку, все как должно быть... отлично, хоть что то проявляется...
Получилось! Победа нах! Вот только логики я так и не понял... Код (Text): invoke GetDC, hWnd mov hdc, eax invoke CreateCompatibleDC, hdc сделал вот так а было вот как Код (Text): invoke CreateDC, NULL, OFFSET PrinterName, NULL, NULL mov hdcPrint, eax invoke CreateCompatibleDC, hdcPrint не пойму зачем нужен хэндл окна при выводе на принтер...
DC - это всего лишь контекст графического устройства. Средство абстрагироваться от оборудования. Поэтому от чего его наследовать - значения не имеет, ибо всё равно потом он будет связан с принтером.
всё равно не совсем ясно... что означает "наследовать"...? функция CreateCompatibleDC, создаёт совместимый, с устройством вывода, контекст. И возвращает его описатель. Принимает тоже хэндл. Возникает вопрос - хэндл чего? Наверное того же что она и возвращает. Иначе как функция поймет, совместимый с чем контекст ей создавать. Вот я и передаю описатель контекста принтера. The GetDC function retrieves a handle to a device context (DC) for the client area of a specified window or for the entire screen. GetDC возвращает контекст устройства клиентской области окна. я правильно понимаю? Так зачем же нам создавать совместимый с клиентской областью окна контекст, мы ведь на принтер выводим? Если контекст клинтской области окна совместим с контекстом принтера, зачем тогда делить эти понятия? И почему тогда не прокатил для функции CreateCompatibleDC хэндл конт. принтера?
"Совместимый" в данной терминологии означает "такой, для создания которого не требуется вручную указывать тучу параметров типа цветовой гаммы, RGB-плоскостей и прочей лабуды". Всё берётся из клонируемого DC. Видел же наверняка, сколь внушительный список параметров имеет CreateDC (я, в частности, про структуру DEVMODE)? И чтоб не грузить прогера такими вещами, была введена функция, "клонирующая" контексты графустройств, ибо на практике менять такие парамы, на отличные от принятых по умолчанию, необходимо крайне редко. Потому что физически они абстрагируют прогу от разных устройств. А совместимыми они быть и должны, т.к. всё же удобнее рисовать - хоть с помощью принтера, хоть на дисплее - с помощью одного набора функций. А то представьте: для отображения, скажем, картинки на монитор нужно ловить прерывание, для отрисовки чего-либо на принтер следует писать цепочку байт в порт, для текстового режима, чтобы написать на экране букофки - надо лезть в память по заданному адресу... Так было в DOS. Ну и ессно ето мало кому нравилось. И тогда мелкософт удачно спёр у кого-то идею так наз. HAL - hardware abstraction layer. Так что теперь разрабу не приходится судорожно дописывать в программу номера портов, по которым нужно отсылать символы на печать, и вручную кодить реализацию форматов такой передачи - дрова всё сделают за него. И понизят гамму, если принтер не поддерживает 32 битный цвет, и переведут картинку в ч/б если в принтере нет цветного картриджа... Ляпота одним словом Наверное, потому что хендл был фиктивным (я не утверждаю, я предполагаю. могу и ошибаться. пусть профи, если сюда зайдут, поправят) - ты ж ничего ему не задал. Везде стояли нули! Ну а от чего тогда наследоваться-то?
и еще два слова: для получения контекста принтера, функцией CreateDC, достаточно всего одного аргумента - имя принтера... я, кстати, получил это имя ооочень хитрым способом - случайно распечатал пробную XP-шную страницу печати, и там обнаружил имя принтера... с функцией EnumPrinters не разобрался... и все работает!