AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.02.2006, 15:28   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
WinAPI. Ссылка (POINT) третьего уровня вложенности
AXAPTA 2.5 SP3

Заранее извиняюсь, за слишком длинный код, но все-равно в результате пришлось бы его привести.

Цель приведенного ниже кода - это получить список очереди на печать и определить, есть ли в этой очереди документ с заранее известным именем.

Проблема в следующем.

Очередь на печать я получаю при помощи API-функции enumJobs. Результат работы этой функции - это массив структур. Сами структуры, в свою очередь, имеют внутри себя ссылки на текстовые строки.

Т.е., получаю конструкцию, с 3 уровнями вложенности ссылок.

Уже целый день угробил, но никак не могу получить значение по этим сслкам на текстовые данные. Сами ссылки на область памяти, где они храняться, получаю, а как получить значения?

PHP код:
static void PrintSpooler(Args _args)
{
    
#WinAPI
    #define.MAX_PATH(260)
    #define.StructSizeINFO_1(64)

    // Чтение win.ini или реестра
    
Dll             kernel32            = new Dll("kernel32.dll");
    
DllFunction     getProfileString    = new DllFunction(kernel32"GetProfileStringA");   // Чтение win.ini или реестра

    
Binary          appName             = new Binary(#MAX_PATH),
                    
keyName             = new Binary(#MAX_PATH),
                    
defaultValue        = new Binary(#MAX_PATH),
                    
returnedString      = new Binary(#MAX_PATH);
    
int             hr;
    
str             strValue;
    
TextBuffer      textBuffer = new TextBuffer();

    
// Работа со спуллером принтера
    
Dll             winspool            = new Dll("winspool.drv");
    
DllFunction     openPrinter         = new DllFunction(winspool"OpenPrinterA"),    // открытие принтера
                    
enumJobs            = new DllFunction(winspool"EnumJobsA"),       // чтение заданий принтера
                    
getProcessHeap      = new DllFunction(kernel32"GetProcessHeap"),
                    
heapAlloc           = new DllFunction(kernel32"HeapAlloc"),
                    
rtlMoveMemory       = new DllFunction(kernel32"RtlMoveMemory");

    
Binary          printerName         = new Binary(#MAX_PATH),
                    
printerHWNDPointer  = new Binary(#MAX_PATH),
                    
printerDefault      = new Binary(#MAX_PATH),
                    
pJob                = new Binary(4),
                    
pcbNeeded           = new Binary(4),
                    
pcReturned          = new Binary(4),
                    
strINFO;

    
int             printerHandle,
                    
printerJobSize,
                    
processHeap,
                    
printerJob,
                    
numJob,
                    
nextJob,
                    
nextOFF_SET;
    ;

    
//---------------------------------------------------------------------------------- Имя принтера по умолчанию
    
getProfileString.returns(ExtTypes::DWORD);
    
getProfileString.arg(ExtTypes::POINTER,      // lpAppName,                // address of section name
                         
ExtTypes::POINTER,      // LPCTSTR lpKeyName,        // address of key name
                         
ExtTypes::POINTER,      // LPCTSTR lpDefault,        // address of default string
                         
ExtTypes::POINTER,      // LPTSTR lpReturnedString,  // address of destination buffer
                         
ExtTypes::DWORD);       // DWORD nSize               // size of destination buffer

    
appName.string(0,"Windows");
    
keyName.string(0,"Device");
    
defaultValue.string(0,",,,");
    
hr getProfileString.call(appNamekeyNamedefaultValuereturnedString#MAX_PATH);

    
if (hr == 0)
    {
        print 
WinApi::getLastError();
    }
    else
    {
        
strValue returnedString.string(0);
//        print strValue; // то, что реально прочитали из реестра
        // Собственно имя принтера - это строка до первой запятой
        
textBuffer.setText(strValue);
        
textBuffer.nextToken(false",");
        
strValue textBuffer.token();
        print 
strValue;
    }

    
//--------------------------------------------------------------------------------- Открытие контекста принтера
    
openPrinter.returns(ExtTypes::DWORD);
    
openPrinter.arg(ExtTypes::POINTER,      // LPTSTR pPrinterName, // pointer to printer or server name
                    
ExtTypes::POINTER,      // LPHANDLE phPrinter,  // pointer to printer or server handle
                    
ExtTypes::POINTER);     // LPPRINTER_DEFAULTS pDefault // pointer to printer defaults structure

    
printerName.string(0,strValue);
    
printerDefault.string(0,"");
    
printerHWNDPointer.dWord(0);
    
hr openPrinter.call(printerNameprinterHWNDPointerprinterDefault);
    
printerHandle printerHWNDPointer.dWord(0);

    print 
"hr= ",hr" printerHandle= ",printerHandle;

    
//--------------------------------------------------------------------------------------------------- Очередь на печать
    
enumJobs.returns(ExtTypes::DWORD);
    
enumJobs.arg(ExtTypes::DWORD,           //  HANDLE hPrinter,    // handle to printer object
                 
ExtTypes::DWORD,           //  DWORD FirstJob,     // location of first job in print queue to enumerate
                 
ExtTypes::DWORD,           //  DWORD NoJobs,       // number of jobs to enumerate
                 
ExtTypes::DWORD,           //  DWORD Level,        // structure level
                 
ExtTypes::POINTER,         //  LPBYTE pJob,        // pointer to structure array
                 
ExtTypes::DWORD,           //  DWORD cbBuf,        // size of array, in bytes
                 
ExtTypes::POINTER,         //  LPDWORD pcbNeeded,  // addr. of variable with no. of bytes copied
                                            // (or required)
                 
ExtTypes::POINTER);        //  LPDWORD pcReturned  // addr. of variable with no. of job info. structures copied

    //------------------------------------------------------ Сначала получаю ссылку на количество байт в результате работы функции
    
pJob.dWord(0);
    
pcbNeeded.dWord(0);
    
pcReturned.dWord(0);

    
// Вычисляю размер данных
    
hr enumJobs.call(printerHandle,0,127,1,pJob,0,pcbNeeded,pcReturned);
    
printerJobSize pcbNeeded.dWord(0);

    print 
"hr= ",hr" printerJobSize= ",printerJobSize;

    if (! 
hr)
    {
        
// Будет ошибка 122 (не хватает места) - это нормально
        
print WinAPI::getLastError(), " (должно быть 122)";
    }

    if (! 
printerJobSize)
    {
        
// В очереди нет заданий на печать
        
print 'no print';
        
pause;
        
// Закрытие контекста принтера
        
WinApi::closeHandle(printerHandle);
        return;
    }

    
//--------------------------------------------------------------------------------- Собственно получение очереди на печать
    /*
    // Непонятно как и куда приткнуть эту структуру. И надо ли?
    job_INFO_1 = new Binary(printerJobSize);
    job_INFO_1.dWord(0,0);                  //    DWORD  JobId;
    job_INFO_1.binary(4,pPrinterName);      //    LPTSTR pPrinterName;
    job_INFO_1.binary(8,pMachineName);      //    LPTSTR pMachineName;
    job_INFO_1.binary(12,pUserName);        //    LPTSTR pUserName;
    job_INFO_1.binary(16,pDocument);        //    LPTSTR pDocument;
    job_INFO_1.binary(20,pDatatype);        //    LPTSTR pDatatype;
    job_INFO_1.binary(24,pStatus);          //    LPTSTR pStatus;
    job_INFO_1.dWord(28,0);                 //    DWORD  Status;
    job_INFO_1.dWord(32,0);                 //    DWORD  Priority;
    job_INFO_1.dWord(36,0);                 //    DWORD  Position;
    job_INFO_1.dWord(40,0);                 //    DWORD  TotalPages;
    job_INFO_1.dWord(44,0);                 //    DWORD  PagesPrinted;
    job_INFO_1.binary(48,systemTime);       //    SYSTEMTIME Submitted;
    */
    
pJob = new Binary(printerJobSize);
    
pcReturned.dWord(0);
    
pcbNeeded.dWord(0);

    
hr enumJobs.call(printerHandle,0,127,1,pJob,printerJobSize,pcbNeeded,pcReturned);
    
numJob pcReturned.dWord(0);

    for (
nextJob 1nextJob <= numJobnextJob++)
    {
        
nextOFF_SET = (nextJob 1)*#StructSizeINFO_1;

        
print " pJob="pJob.dWord(nextOFF_SET),
              
" totalPages=",pJob.dWord(nextOFF_SET+40),
              
" принтер=",pJob.dWord(nextOFF_SET+4),     // ссылка на область памяти, где хранится имя принтера
              
" документ=",pJob.dWord(nextOFF_SET+16);   // ссылка на область памяти, где хранится имя документа
    
}

    if (! 
hr)
    {
        print 
WinAPI::getLastError();
    }

    
//--------------------------------------------------------------------------------------------- Закрытие контекста принтера
    
WinApi::closeHandle(printerHandle);

    
pause;
    return;

AXAPTA 2.5 SP3
Старый 06.02.2006, 16:04   #2  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
X++:
Binary prnName;

...
prnName = new Binary(256);
prnName.Attach(pJob.dWord(nextOFF_SET+4), 255);
prnName.string(0);
__________________
Axapta v.3.0 sp5 kr2
Старый 06.02.2006, 16:28   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Спасибо. Заработало!

PS:
Не могли нормальный HELP написать. Редиски...
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX: Dynamics AX - Why it's good: Value point two, "The Stack" Blog bot DAX Blogs 1 13.11.2008 13:30
Axapta WinAPI::SewWindow... кто знает как? UNRW DAX: Программирование 2 26.09.2008 15:28
Dynamics AX Geek: Finding files with WinAPI Blog bot DAX Blogs 0 28.10.2006 16:40
WinAPI::getLastError() DreamCreator DAX: Программирование 4 20.06.2005 10:03
WinApi. Удаление файлов глючит. NJD DAX: Программирование 10 05.12.2003 13:31

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:07.