недостаточно буфера при вызове DocumentProperties, также глобальная разблокировка не разблокирует - PullRequest
0 голосов
/ 11 мая 2010

см. Встроенные комментарии

bool res = false;
DWORD dwNeeded = DocumentPropertiesW(NULL, m_currPrinterHandle, (LPWSTR) m_currPrinterName.c_str(), NULL, NULL, 0); 
if (m_devmode_buf)
{
    GlobalFree(m_devmode_buf);      
}
m_devmode_buf = GlobalAlloc(GPTR, dwNeeded);
GetLastError(); // = 0;
if (m_devmode_buf)
{
    LPDEVMODEW devmode_buf = (LPDEVMODEW) GlobalLock(m_devmode_buf);        
    GetLastError(); // = 0
    if (devmode_buf)
    {           
        if (devmode_buf)
        {
            lala = DocumentPropertiesW(NULL, m_currPrinterHandle, (LPWSTR) m_currPrinterName.c_str(), devmode_buf, NULL, DM_OUT_BUFFER);
            if (lala == IDOK)
            {
                res = true;
            }
            GetLastError(); // = 122. insufficient buffer here. why????
        }
        UInt32 res1 = GlobalUnlock(m_devmode_buf); // res1 is 1. should be 0
        res2 = GetLastError(); // = 0
        if (!(res1 == 0 && (res2 == ERROR_NOT_LOCKED || res2 == NO_ERROR)))
        {
            //res = false;
        }           
    }
}

Ответы [ 3 ]

1 голос
/ 11 мая 2010

Если второй вызов DocumentProperties () возвращает 1 (т. Е. IDOK), то он не вызывает сбоев, поэтому значение GetLastError () не имеет смысла. Вероятно, это ожидаемое условие, которое возникает и обрабатывается внутри DocumentProperties (). Соглашение об использовании GetLastError () заключается в том, что вы устанавливаете его только при сбое; Вы обычно не очищаете это на успехе. Это зависит от документации каждой отдельной функции, чтобы объяснить, как возвращаются ошибки. В документации для DocumentProperties () даже не упоминается GetLastError (), поэтому проверка его вообще может быть бессмысленной (хотя обычно можно с уверенностью предположить, что все функции Win32 возвращают ошибки через GetLastError ()).

0 голосов
/ 30 мая 2012

DocumentProperties вернет -1 для размера DEVMODE для определенных машин при определенных обстоятельствах - на форумах MS есть целая ветка об этом (началось около 2008 года), но MS не видит это как проблему, несмотря на то, что их пример кода никогда проверка кода возврата (или общего диалогового окна PrintDlg (), которое с радостью пытается выделить -1 память и завершается ошибкой).

Вы просто не можете полагаться исключительно на эту функцию, поскольку она может работать на вашем компьютере, но не работать на клиентском компьютере. Проверьте на -1 и, если он вернется, просто составьте большое число (2 * sizeof (DEVMODE) или что-то еще) и используйте его.

0 голосов
/ 11 мая 2010

Вам не нужно вызывать GlobalLock, поскольку вы передали GPTR в GlobalAlloc.Вам нужно вызывать GlobalLock только тогда, когда вы передаете GMEM_MOVEABLE.

Но вы не должны использовать GlobalAlloc / GlobalFree, если в документации по API, которому вы передаете память, не сказано иначе.Предпочитаю HeapAlloc / HeapFree или просто new / delete.GlobalAlloc - это более старый API, предназначенный для совместимости с 16-битной Windows.

...