vazzzzz
| Редактировать | Цитировать | Сообщить модератору Zloy_Gelud Спасибо вам за информацию, только что приехал и попробовал наваять чего-нить. Но как-то не вышло сходу (хотя все до функции SetDIBitsToDevice "заработало" сразу и выдало уведомление об "успехе"). Но в итоге функция вернула "0" (( Что-то я не так делаю, прошу еще раз пендаль волшебный (взгляните на мои "труды" если не сложно). Код: local disp = {}; disp.Width = 800; disp.Height = 600; disp.Handle = Application.GetWndHandle(); disp.DevCH = DLL.CallFunction("User32.dll", "GetDC", disp.Handle, DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL); --создание структуры, описывающей bitmap изображение (BITMAPINFO) local BITMAPINFO = MemoryEx.DefineStruct { DWORD ("biSize", disp.Width * disp.Height * 3); INT ("biWidth", disp.Width); INT ("biHeight", disp.Height); WORD ("biPlanes", 1); WORD ("biBitCount", 24); DWORD ("biCompression", 0); DWORD ("biSizeImage", 0); INT ("XPelsPerMeter"); --что это? INT ("YPelsPerMeter"); --что это? DWORD ("biClrUsed", 0); DWORD ("biClrImportant", 0); DWORD ("biRGBQuad", 0); --что это? }; apper1 = Application.GetLastError(); --получение указателя на структуру BITMAPINFO local hBITMAPINFO = BITMAPINFO:New(); apper2 = Application.GetLastError(); local pBITMAPINFO = hBITMAPINFO:GetPointer(); apper3 = Application.GetLastError(); --создание массива из disp.Width * disp.Height * 3 байт для указания цветов каждого пикселя disp.BMHandle = MemoryEx.Allocate(disp.Width * disp.Height * 3); apper4 = Application.GetLastError(); -- if (disp.Handle > -1 and disp.DevCH ~= "") then if (apper1 == 0 and apper2 == 0 and apper3 == 0 and apper4 == 0) then --если все OK disp.args = disp.DevCH .. ",0,0," .. tostring(disp.Width) .. "," .. tostring(disp.Height) .. ",0,0,0," .. tostring(disp.Height) .. "," .. disp.BMHandle .. "," .. pBITMAPINFO .. ",0"; -- в функции StretchDIBits использовать pBITMAPINFO в качестве указателя на структуру BITMAPINFO dispIsOK = DLL.CallFunction("gdi32.dll", "SetDIBitsToDevice", disp.args, DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL); apper1 = Application.GetLastError(); hBITMAPINFO:Free(); apper2 = Application.GetLastError(); if (dispIsOK ~= "") then if (apper1 == 0 and apper2 == 0) then message = "Успешно!\n\n"; message = message .. "Структура: " .. disp.DevCH .. "\n"; message = message .. "BitmapInfo: " .. pBITMAPINFO .. "\n"; message = message .. "Bitmap: " .. disp.BMHandle .. "\n"; message = message .. "Результат: " .. dispIsOK; Dialog.Message("Уведомление", message, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1); else Dialog.Message("Ошибка", "Не удалось удалить структуру BITMAPINFO!", MB_OK, MB_ICONSTOP, MB_DEFBUTTON1); end else Dialog.Message("Ошибка", "Не удалось вывести bitmap!", MB_OK, MB_ICONSTOP, MB_DEFBUTTON1); end else Dialog.Message("Ошибка", "Не удалось выделить память!", MB_OK, MB_ICONSTOP, MB_DEFBUTTON1); end if (DLL.CallFunction("User32.dll", "ReleaseDC", disp.Handle .. "," .. disp.DevCH, DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL) == "") then Dialog.Message("Ошибка", "Не удалось удалить контекст устройства!", MB_OK, MB_ICONSTOP, MB_DEFBUTTON1); end else Dialog.Message("Ошибка", "Не удалось создать контекст устройства!", MB_OK, MB_ICONSTOP, MB_DEFBUTTON1); end | Пояснения: я выделяю массив по 3 байта на пиксель и ничего туда не пишу, потому как мне б "хоть что-то" для начала вывести на экран (хоть все черное, хоть все белое, да хоть пурпурное - лишь бы пощупать функцию для начала). Как я понимаю в изначально выделенных байтах будет либо 0x000000 либо 0xFFFFFF (на каждый пиксель)? Или я ошибаюсь? С NULLом не оч дружу (в плане осознания), может это и губит? Добавлено: Zloy_Gelud Еще наблюдаю периодически странное пока для меня явление: иногда функция GetDC возвращает отрицательный хэндл для контекста окна. Совершенно не предсказуемо. И еще одна странность - если я устанавливаю в настройках проекта "запускать от имени администратора", то эффект выдачи отрицательного хэндла проявляется чаще, чем при обычном запуске (As invoker). И это меня слегка пугает, т.к. сейчас я вызываю функцию однократно, а что будет когда я буду кадры отрисовывать 100 раз в секунду?.. Отрицательный хэндл имеется в виду не "-1", а "-179832749238" (ну или типа того). Пробовал устанавливать и DLL_RETURN_TYPE_LONG (первая мысль возникла, что причина в изменении старшего бита переменной и из-за этого число становится отрицательным) - не помогло, все равно иногда проскакивает отрицательное число. |