mkdir

Тема в разделе "WASM.BEGINNERS", создана пользователем hakeem, 24 авг 2008.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    l_inc
    не катит - возвращает 0 в ответ на handle BitMap...
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Да... уже забыл... но можно использовать GdipCreateBitmapFromHBITMAP.
     
  3. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Y_Mur
    Да и про CloseClipboard, чем чревато если не вызвать эту функцию? У меня вроде все работает при снимке экрана, только второй уже не получается...
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    пока ты держишь clipoboard открытым никто не имеет нему доступа кроме твоей проги, впрочем при закрытии программы все её ресурсы освобождаются автоматически, но лучше этим не злоупотреблять, а приучить себя сразу закрывать всё ненужное ;)
     
  5. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Вот оно чё...
    Спасибо
     
  6. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Извините можно поподробнее про это?
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Код (Text):
    1.     Описание формата BMP для Window 3.0 (DIB)
    2.     =========================================
    3.     Основным  отличием  файлов  нового  формата  (DIB)  -   Device
    4.  Independent Bitmap (аппаратно-независимый битовый образ) является
    5.  то, что в них используется кодировка цветов с одной битовой плос-
    6.  костью.
    7.     Файлы битовых образов нового формата начинаются  со  структуры
    8.  BITMAPFILEHEADER:
    9.  
    10.     typedef struct tagBITMAPFILEHEADER {
    11.     word    bfType;     //тип файла (для битового образа - BM)
    12.     dword   bfSize;     //размер файла в dword
    13.     word    bfReserved1;    //не используется
    14.     word    bfReserved2;    //не используется
    15.     dword   bfOffbits;  //смещение данных битового образа от
    16.                 //заголовка в байтах
    17.  
    18.     }
    19.     Непосредственно за ней располагается структура BITMAPINFO, со-
    20.  держащая всю информацию о битовом образе. Она делится на две час-
    21.  ти: структуру BITMAPINFOHEADER, описывающей  размеры  и  цветовой
    22.  формат битового образа, и массив структур  RGBQUAD,  определяющей
    23.  цветовую палитру:
    24.  
    25.     typedef struct tagBITMAPINFO {
    26.     BITMAPINFOHEADER     bmiHeader;
    27.     RGBQUAD      bmiColors[1];
    28.     }
    29.  
    30.     typedef struct tagBITMAPINFOHEADER {
    31.     dword   biSize;     //число байт, занимаемых структурой
    32.                 //BITMAPINFOHEADER
    33.     dword   biWidth;    //ширина битового образа в пикселах
    34.     dword   biHeight;   //высота битового образа в пикселах
    35.     word    biPlanes;   //число битовых плоскостей устройства
    36.     word    biBitCount; //число битов на пиксель
    37.     dword   biCompression;  //тип сжатия
    38.     dword   biSizeImage;    //размер картинки в байтах
    39.     dword   biXPelsPerMeter;//горизонтальное разрешение устройства,
    40.                 //пиксел/м
    41.     dword   biYPelPerMeter; //вертикальное разрешение устройства,
    42.                 //пиксел/м
    43.     dword   biClrUsed;  //число используемых цветов
    44.     dword   biClrImportant; //число "важных" цветов
    45.     } BITMAPINFOHEADER;
    46.  
    47.     Более подробно:
    48.  
    49.     biSize - обычно используется для облегчения доступа  к таблице
    50.  цветов.
    51.  
    52.     biPlanes - определяет число битовых плоскостей;  однако,   по-
    53.  скольку цвет кодируется последовательными битами, это число всег-
    54.  да равно 1.
    55.  
    56.     biBitCount - этим полем определяется число  цветов, используе-
    57.  мых битовым образом. В зависимости от способа  кодирования, может
    58.  принимать значения:
    59.     1 - битовый образ монохромный, и таблица цветов  должна содер-
    60.  жать два элемента. Каждый бит в массиве данных кодирует один пик-
    61.  сел. Если значение бита - 0, то пиксел становится  первым  цветом
    62.  таблицы; если - 1, пиксел становится вторым цветом таблицы.
    63.     4 - битовый образ имеет максимум 16 цветов, и массив bmiColors
    64.  (таблица цветов) имеет до 16 элементов. Цвет каждого  пиксела оп-
    65.  ределяется по таблице цветов при помощи  четырехбитного  индекса.
    66.  Например, если первый байт данных  имеет  значение  3Ah,  то  при
    67.  отображении битового образа цвет первого пиксела  определяет чет-
    68.  вертый элемент таблицы цветов, а цвет второго - одиннадцатый.
    69.     8 - битовый образ имеет максимум 256 цветов, и  таблица цветов
    70.  имеет до 256 элементов. Каждый  байт  массива  данных  определяет
    71.  цвет одного пиксела.
    72.     24 - битовый образ имеет максимум 2  в  24-й  степени  цветов.
    73.  Таблица цветов пуста, а цвет пикселов  определяется  пакетами  из
    74.  трех байтов, описывающими цветовые интенсивности  красного, зеле-
    75.  ного и голубого цветов.
    76.  
    77.     biCompression - тип сжатия. Может принимать значения:
    78.     BI_RGB - сжатие отсутствует;
    79.     BI_RLE8 - сжатие для формата 8 бит на пиксел;
    80.     BI_RLE4 - сжатие для формата 4 бита на пиксел.
    81.  
    82.     biXPelsPerMeter и biYPelsPerMeter - могут  использоваться  для
    83.  выбора из списка ресурсов пиктограммы,  наиболее  подходящей  для
    84.  данного устройства.
    85.  
    86.     biClrUsed - число цветов, используемых данныи битовым образом.
    87.  Если 0, то используются все цвета палитры  (указанные  в  массиве
    88.  bmiColors).
    89.  
    90.     biClrImportant - используется для управления  алгоритмом отоб-
    91.  ражения цветов. Так, если четыре различных  приложения отображают
    92.  на экране по одному битовому образу с 75 цветами каждый, то адап-
    93.  тер, выводящий 256 цветов одновременно, не  сможет  полностью ау-
    94.  тентично отобразить на экране все 4 картинки. В  этом  случае ис-
    95.  пользуется механизм замены цветов - ищется битовый  образ  с наи-
    96.  меньшим приоритетом и его "лишние" цвета заменяются наиболее под-
    97.  ходящими.
    98.  
    99.     typedef struct tagRGBQUAD {
    100.     byte    rgbRed;     //интенсивность красного
    101.     byte    rgbGreen;   //интенсивность зеленого
    102.     byte    rgbBlue;    //интенсивность голубого
    103.     byte    rgbRserved; //не используется
    104.     } RGBQUAD;
    105.  
    106.     После того, как все параметры битового  образа  определены,  в
    107.  файле идут сами  скан-строки  битовой  плоскости,  причем  первой
    108.  скан-строкой в формате DIB считается нижняя скан-строка (т.е. на-
    109.  чало координат находится в левом нижнем углу изображения).
    110.  
    111.     Скан-строки выровнены по 32-битной границе - dword !!!
    Получишь адрес BITMAPINFOHEADER, через biSize от него будет палитра RGBQUAD размером biClrUsed*4 или 256*4 если biClrUsed=0 или её не будет если biBitCount=24 ;) Затем будет сама картинка выравненнная на 4 байтную границу размером biSizeImage (про возможность другого порядка эт я малость перепутал - давно с этим не играл, единственное что - в современном варианте больше полей чем в этом древнем переводе, но biSize это учитывает ;). Тебе нужно на основании этого посчитать и заполнить BITMAPFILEHEADER, записать его, затем записать блок памяти начинающийся с полученного из буфера BITMAPINFOHEADER и размером который посчитаешь ;) Ну и закрыть файл ;)
    Успешной медитации ;)
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Ну и зачем этот геморрой, если есть GdipCreateBitmapFromHBITMAP? К тому же можно при этом также обойтись без CreateFile и иже с ним, а использовать GdipSaveImageToFile. И вообще, если цель - сохранение снимка экрана, то буфер обмена - далеко не лучший способ.
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    l_inc
    Я так понял цель - освоить работу с буфером, файлами и картинками - потому и указываю путь для медитации ;)
    А русскую справку по нюансам GDI+ для асма он имхо всё равно не найдёт, да и на английском msdn вся основная справка в объектно плюсованной форме ;), посему бегиннеерсу разобраться сначала в этой справке, а потом в табличке перевода ++ в доступную из асма flat версию функций геморою точно не меньше, а познавательная сторона медитации над устройством обычного GDI имхо в любом случае штука пользительная ;)
     
  10. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Теперь я начил понимать о чем говорил Subrealist:

    Код (Text):
    1. void SaveScreen(HWND hWnd)
    2. {
    3.     HDC hDC, CompDC;
    4.     SYSTEMTIME SysTm;
    5.     BITMAP bmp;
    6.     PBITMAPINFO pbmi;
    7.     HBITMAP hBitmap;
    8.     BITMAPFILEHEADER BFHeader;
    9.     WORD ClrBits;
    10.     DWORD dwTmp;
    11.     LPBYTE lpBits;
    12.     HANDLE hFile;
    13.     char FileName[22], dir[MAX_PATH];
    14.  
    15.     hDC=GetDC(hWnd);
    16.    
    17.     CompDC=CreateCompatibleDC(hDC);
    18.     hBitmap=CreateCompatibleBitmap(hDC, XSize, YSize);
    19.     SelectObject(CompDC,hBitmap);
    20.     BitBlt(CompDC,0,0,XSize,YSize,hDC,0,0,SRCCOPY);
    21.     ReleaseDC(hWnd, hDC);
    22.     GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmp);
    23.     ClrBits=(WORD)bmp.bmPlanes*bmp.bmBitsPixel;
    24.     strcpy(dir,ScreenSaveDir);
    25.     if(ClrBits<=16)
    26.     {
    27.         ClrBits=16;
    28.     }
    29.     else
    30.     {
    31.         if(ClrBits<=24)
    32.         {
    33.             ClrBits=24;
    34.         }
    35.         else
    36.         {
    37.             ClrBits=32;
    38.         }
    39.     }
    40.    
    41.         pbmi=(PBITMAPINFO)new BYTE [sizeof(BITMAPINFOHEADER)];
    42.    
    43.     pbmi->bmiHeader.biClrUsed=0;
    44.     pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    45.     pbmi->bmiHeader.biWidth=bmp.bmWidth;
    46.     pbmi->bmiHeader.biHeight=bmp.bmHeight;
    47.     pbmi->bmiHeader.biPlanes=bmp.bmPlanes;
    48.     pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;
    49.     if(ClrBits<24)
    50.     {
    51.         pbmi->bmiHeader.biClrUsed=2^ClrBits;
    52.     }
    53.     pbmi->bmiHeader.biCompression=BI_RGB;
    54.     pbmi->bmiHeader.biSizeImage=(pbmi->bmiHeader.biWidth)*pbmi->bmiHeader.biHeight*(ClrBits/8);
    55.     pbmi->bmiHeader.biClrImportant=0;
    56.     lpBits= (UCHAR*)VirtualAlloc(NULL, pbmi->bmiHeader.biSizeImage, MEM_TOP_DOWN | MEM_COMMIT, PAGE_READWRITE);
    57.     GetDIBits(CompDC, hBitmap,0,pbmi->bmiHeader.biHeight,lpBits,pbmi,DIB_RGB_COLORS);
    58.     GetLocalTime(&SysTm);
    59.     sprintf(FileName,"\\%hu%02hu%02hu%02hu%02hu%02hu%03hu.bmp", SysTm.wYear,SysTm.wMonth,SysTm.wDay,SysTm.wHour,SysTm.wMinute,SysTm.wSecond,SysTm.wMilliseconds);
    60.     strcat(dir,FileName);
    61.     hFile=CreateFile(dir,GENERIC_READ|GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
    62.     BFHeader.bfType=0x4d42;
    63.     BFHeader.bfSize=sizeof(BITMAPFILEHEADER)+pbmi->bmiHeader.biSize+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD)+pbmi->bmiHeader.biSizeImage;
    64.     BFHeader.bfReserved1=0;
    65.     BFHeader.bfReserved2=0;
    66.     BFHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+pbmi->bmiHeader.biSize+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD);
    67.     WriteFile(hFile, &BFHeader, sizeof(BITMAPFILEHEADER),(LPDWORD)&dwTmp,0);
    68.     WriteFile(hFile, pbmi,sizeof(BITMAPINFOHEADER)+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD),(LPDWORD)&dwTmp,0);
    69.     WriteFile(hFile,lpBits,pbmi->bmiHeader.biSizeImage,&dwTmp,0);
    70.     CloseHandle(hFile);
    71.  
    72.     DeleteDC(CompDC);
    73.     DeleteObject(hBitmap);
    74.     VirtualFree(lpBits, 0, MEM_RELEASE) ;
    75.     delete pbmi;
    76. }
     
  11. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Аргумент засчитан. :)
    А в качестве справки можно использовать http://com.it-berater.org/gdiplus/GdiPlus.htm По крайней мере мне вполне хватало. Там есть прототипы в Basic-синтаксисе, которые редко кому непонятны.
     
  12. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Весь net перерыл, не смог найти примера как это сделать...
     
  13. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Правильно, ли я определил адрес ?

    Код (Text):
    1. .data ?
    2. bmfh BITMAPFILEHEADER ?
    3. bmih BITMAPINFOHEADER ?
    4.  
    5. .code
    6. mov eax, bmih
    7.   add  eax, sizeof BITMAPFILEHEADER
    8.   mov bmfh, [eax]
     
  14. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Как определить адрес структуры BITMAPFILEHEADER, относительно BITMAPINFOHEADER?
     
  15. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Y_Mur

    Вобщем застрял я;

    Код (Text):
    1. .386
    2.       .model flat, stdcall
    3.       option casemap :none   ; case sensitive
    4. ;------------------------------------------------------------------------
    5.       include \masm32\include\windows.inc
    6.       include \masm32\include\user32.inc
    7.       include \masm32\include\kernel32.inc
    8.       includelib \masm32\lib\user32.lib
    9.       includelib \masm32\lib\kernel32.lib
    10. ;------------------------------------------------------------------------
    11.  
    12. ;------------------------------------------------------------------------
    13.     .data
    14. File_Name db "MyBMP.bmp", 0
    15. ;------------------------------------------------------------------------
    16.     .data ?
    17. dwTmp dw ?
    18. bmfh BITMAPFILEHEADER ?; Заголовок файла изображения
    19. bmih BITMAPINFOHEADER ?; Информационная структура изображения
    20. hFile db ?
    21. ;------------------------------------------------------------------------
    22.     .code
    23.  
    24. start:
    25. invoke keybd_event,VK_SNAPSHOT,0,0,0; Имитируем нажатие клавиши Print Screen
    26.  
    27.                     ; читаем из буфера
    28. invoke OpenClipboard,  hWnd; Открываем буфер
    29. invoke GetClipboardData, CF_DIB;
    30. mov bmih,eax; В eax -адрес BITMAPINFO
    31. invoke CloseClipboard; Закрываем буфер
    32.    xor eax,eax ; обнуляем eax
    33. ;------------------------------------------------------------------------
    34. ;Заполняем структуру BITMAPFILEHEADER
    35.   mov bmfh.bfType, BM ;  тип файла (для битового образа - BM)    
    36.   mov bmfh.bfSize, sizeof BITMAPFILEHEADER ; размер файла      
    37.   mov bmfh.bfReserved1, 0  
    38.   mov bmfh.bfReserved2, 0
    39.                       ;------------------------------------------------------------------------
    40.                       add  eax, sizeof BITMAPFILEHEADER
    41.                       add  eax, sizeof BITMAPINFOHEADER
    42.                       add  eax, sizeof RGBQUAD
    43.                       ;------------------------------------------------------------------------
    44.   mov bmfh.bfOffBits,eax; смещение данных битового образа от заголовка
    45.                       xor eax,eax; обнуляем eax
    46.                       mov eax, bmih
    47.                       add  eax, sizeof BITMAPFILEHEADER
    48.                       mov bmfh, [eax]
    49.                       xor eax,eax; обнуляем eax
    50. ;------------------------------------------------------------------------
    51. ;Заполняем структуру BITMAPINFOHEADER
    52.   mov bmih.biSize, sizeof BITMAPINFOHEADER
    53.   mov bmih.biWidth, ?          
    54.   mov bmih.biHeight, ?        
    55.   mov bmih.biPlanes, 1;для цветов кодируемых последовательно , всегда 1          
    56.   mov bmih.biBitCount, 32      
    57.   mov bmih.biCompression, BI_RGB; так, как сжатия нет    
    58.   mov bmih.biSizeImage, 0; Если компрессия не используется (в поле biCompression находится значение BI_RGB), содержимое поля biSizeImage может быть равно 0    
    59.   mov bmih.biXPelsPerMeter,0  
    60.   mov bmih.biYPelsPerMeter,0  
    61.   mov bmih.biClrUsed, 0        
    62.   mov bmih.biClrImportant, 0
    63. ;------------------------------------------------------------------------
    64. ;Заполняем структуру RGBQUAD
    65.  
    66. ;------------------------------------------------------------------------
    67.   invoke CreateFile,offset File_Name , GENERIC_READ or GENERIC_WRITE, 0, 0, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, 0; Содаем файл для битмапа
    68.   mov hFile,eax
    69. ;------------------------------------------------------------------------
    70.   invoke WriteFile hFile, здесь будет адрес BITMAPFILEHEADER , sizeof BITMAPFILEHEADER, offset dwTmp, 0; Записываем заголовок
    71.   invoke WriteFile hFile, bmih, sizeof BITMAPINFOHEADER+sizeof RGBQUAD, offset dwTmp, 0; Записываем информацию о битмапе  
    72.   invoke WriteFile hFile, здесь будет адрес массива бит, bmih.biSizeImage, offset dwTmp, 0; Записываем массив битов
    73. ;------------------------------------------------------------------------
    74. invoke CloseHandle, hFile; закрываем хэндл файла
    75.  
    76.  invoke ExitProcess, 0
    77. end start
     
  16. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Как определить адрес структуры BITMAPFILEHEADER, относительно известного BITMAPINFOHEADER?
     
  17. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    hakeem
    BITMAPFILEHEADER ты определяешь и заполняешь самостоятельно (поскольку ты сам создаёшь файл, а не редактируешь готовый). Располагается BITMAPFILEHEADER в файле перед BITMAPINFOHEADER.
    BITMAPINFOHEADER тебе как раз определять и заполнять не нужно - это сделает тот кто помещает картинку в ClipBoard, а тебе нужно добыть из него информацию
    Код (Text):
    1. .686
    2.  
    3. .model flat,stdcall
    4.       option casemap :none   ; case sensitive
    5.       include \masm32\include\windows.inc
    6.       include \masm32\include\user32.inc
    7.       include \masm32\include\kernel32.inc
    8.       include \masm32\include\comdlg32.inc
    9.  
    10.       includelib \masm32\lib\user32.lib
    11.       includelib \masm32\lib\kernel32.lib
    12.       includelib \masm32\lib\comdlg32.lib
    13.  
    14. ;------------------------------------------------------------------------------------------
    15. ;   Макрофункция для определения строк
    16. ;------------------------------------------------------------------------------------------
    17. ; Строка с завершающим нулём
    18. zSTR MACRO P1, P2
    19. LOCAL zSTRname
    20.   IFB <P2>; Строка без имени
    21.     .data
    22.       zSTRname db P1, 0
    23.     .code
    24.     EXITM <offset zSTRname>
    25.   ELSE    ; Строка с именем
    26.     .data
    27.        P1 db P2, 0
    28.     .code
    29.     EXITM <offset P1>
    30.   ENDIF
    31. ENDM
    32. ; можно вместо этого определять строки в сегменте
    33. ; .data
    34. ; FileName db 'TestBMP.bmp', 0
    35. ; и обращаться к ним по offset FileName
    36. ; но имхо с макросом удобнее, кроме того он позволяет определять и именованные переменные
    37. ; zSTR(szError, 'Ошибка'), к котороым потом можно обращаться offset szError
    38.  
    39. ;======================================================================================================
    40. .data?
    41.   h_File    dd ?
    42.   write_result  dd ? ; результат записи (количество записанных байт)
    43.   szRezult  db 1024 dup (?) ; Строка с результатами
    44.   BMP_File_Header BITMAPFILEHEADER <?>  ; Структура заголовка файла содержащего BITMAP
    45. .code
    46. start:
    47.     invoke OpenClipboard, 0
    48.     invoke GetClipboardData, CF_DIB
    49.       .if eax == 0
    50.          invoke MessageBox, NULL, zSTR('Поместите BitMap в буфер обмена'),\
    51.                       zSTR(szError, 'Ошибка'), MB_ICONERROR or MB_OK
    52.          jmp EndProg
    53.       .endif
    54.     mov edi, eax ; запомнили адрес BitMap (регистры ebx, edi, esi не изменяются при вызове API)
    55.    
    56.     ; === Вычисляем размер файла ===
    57.     mov esi, [edi.BITMAPINFOHEADER.biSize]      ; размер заголовка BitMap (для картинки из буфера)
    58.     ; Размер палитры
    59.     mov eax, [edi.BITMAPINFOHEADER.biClrUsed]
    60.     shl eax, 2  ; biClrUsed * 4 байта = размер палитры
    61.     add esi, eax    ; сложить размер заголовка и палитры
    62.  
    63.    
    64.     ; ==== Заполняем заголовок файла ====
    65.         mov WORD PTR [BMP_File_Header.bfType], 'MB' ; Сигнатура BitMap файла
    66.     add esi, sizeof BITMAPFILEHEADER        ; размер заголовка с учётом выравнивания
    67.     mov [BMP_File_Header.bfOffBits], esi        ; смещение начала картинки в файле
    68.     movzx ebx, WORD PTR [edi.BITMAPINFOHEADER.biBitCount]   ; Количество бит на цвет
    69.     mov eax, [edi.BITMAPINFOHEADER.biSizeImage] ; Размер самой картинки
    70.    
    71.     .if eax == 0    ; значит тот кто писал в буфер схалтурил и придётся считать размер картинки самостоятельно ;)
    72.         mov eax, [edi.BITMAPINFOHEADER.biWidth]
    73.         .if ebx == 1    ; бит на цвет
    74.         shr eax, 3 ; /8 поскольку 8 пикселей на байт
    75.             ; учитываем выравнивание строк на границу DWORD
    76.             mov ecx, eax
    77.             and eax, not 3  ; отбросить младшие два бита
    78.             .if ecx & 3 ; если в них был не ноль
    79.                 add eax, 4  ; то учесть выравнивающие байты
    80.         .endif
    81.         .elseif ebx == 4    ; бита на цвет
    82.         shr eax, 1 ; /2 поскольку 4 бита это 2 пиксела на байт
    83.             ; учитываем выравнивание строк на границу DWORD
    84.             mov ecx, eax
    85.             and eax, not 3  ; отбросить младшие два бита
    86.             .if ecx & 3 ; если в них был не ноль
    87.                 add eax, 4  ; то учесть выравнивающие байты
    88.         .endif
    89.         .elseif ebx == 8    ; бит на цвет (1 байт на пиксел)
    90.             ; учитываем выравнивание строк на границу DWORD
    91.             mov ecx, eax
    92.             and eax, not 3  ; отбросить младшие два бита
    93.             .if ecx & 3 ; если в них был не ноль
    94.                 add eax, 4  ; то учесть выравнивающие байты
    95.         .endif
    96.         .elseif ebx == 24   ; бита на цвет
    97.         shl eax, 1              ; *2
    98.         add eax, [edi.BITMAPINFOHEADER.biWidth] ; *3 поскольку 24 бита это 3 байта на цвет
    99.             ; учитываем выравнивание строк на границу DWORD
    100.             mov ecx, eax
    101.             and eax, not 3  ; отбросить младшие два бита
    102.             .if ecx & 3 ; если в них был не ноль
    103.                 add eax, 4  ; то учесть выравнивающие байты
    104.         .endif
    105.         .elseif ebx == 32
    106.         shl eax, 2 ; *4 - здесь длина строк выравнивается сама собой ;)
    107.         ; зато специфическое выравнивание для начала картинки на 16 байт см. ниже
    108.         .endif
    109.         xor edx, edx ; неявно используется в mul
    110.         mul [edi.BITMAPINFOHEADER.biHeight] ; edx:eax * biHeight = размер картинки в байтах
    111.         mov [edi.BITMAPINFOHEADER.biSizeImage], eax ; пусть теперь хоть в файле сохранится :)
    112.     .endif
    113.    
    114.     .if ebx == 32   ; учитываем выравнивание для начала 32битной картинки
    115.         add esi, 12
    116.         mov [BMP_File_Header.bfOffBits], esi
    117.     .endif
    118.    
    119.     add esi, eax    ; наконец добавляем размер картинки
    120.     mov [BMP_File_Header.bfSize], esi   ; размер файла сохраняем в его заголовке
    121.  
    122.    
    123.     ; ===== Информация о результатах =====
    124.     invoke wsprintf, addr szRezult, zSTR(<'Размер файла %d байт', 13, 10, 'Глубина цвета %d бит', 13, 10, 'В палитре %d цветов'>), \
    125.         [BMP_File_Header.bfSize], ebx, [edi.BITMAPINFOHEADER.biClrUsed]
    126.     invoke MessageBox, NULL, addr szRezult, zSTR('Параметры BitMap'), MB_OK
    127.  
    128.    
    129.     invoke CreateFile, zSTR('TestBMP.bmp'), GENERIC_READ or GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
    130.       .if eax == INVALID_HANDLE_VALUE
    131.          invoke MessageBox, NULL, zSTR('Не удалось создать файл'),\
    132.                       offset szError, MB_ICONERROR or MB_OK
    133.          jmp EndProg
    134.       .endif
    135.     mov [h_File], eax
    136.    
    137.        
    138.     ; --- Запись подготовленного заголовка файла ---
    139.     invoke WriteFile, [h_File], offset BMP_File_Header, sizeof BMP_File_Header, offset write_result, 0
    140.     ; --- Запись BITMAP (непосредственно из буфера обмена) ---
    141.     invoke WriteFile, [h_File], edi, [BMP_File_Header.bfSize], offset write_result, 0
    142.     invoke CloseHandle, [h_File]    ; Файл записан закрываем
    143.     ; если кроме записи BitMap нужно что-то ещё, то обязательно сначала скопировать BitMap в свою память и сразу закрыть ClipBoard
    144.     invoke CloseClipboard
    145.    
    146. EndProg:
    147.    invoke ExitProcess, NULL
    148. end start
    l_inc
    А ты енту GdipSaveImageToFile сам пробовал?
    У меня она создаёт файл и обламывается с левыми кодами ошибки ничего туда не записав...
    Правда может потому что
    GUID ImageFormatBMP, 0b96b3cabh, 0728h, 11d3h, 9dh, 7bh, 00h, 00h, 0f8h, 1eh, 0f3h, 2eh
    брал из инклюд, поскольку добывать его перечислением как советует M$ чего-то не очень радует
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Пробовал вообще. И вполне прокатывал стандартный GUID. На сях (в предписаном ООП-шном виде) отрабатывал и на VB отрабатывал (в функциональном виде). На асме не пробовал: сегодня к вечеру попробую.
     
  19. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Охладили пыл
    Спасибо, скомпилил Ваш пример. Довольно эфектно, с информацией о параметрах bitmap
    Значит я не в ту сторону копал... И особенно понравилось про пляску с бубном...(представить только)
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    hakeem
    Это совершенно напрасно ;)
    Просто ты случайно ступил на скользкую почву BitMap-ов ;) А так большинство задач решается просто и изящно ;)
    Осваивай Исцелиона - многое прояснится ;)
    Русское описание API конечно в разных видах попадается, но и английского MSDN бояться не стоит - он там писан индусами для индусов потому упрощён дальше некуда ;) и осваивается легко, тем более наглядных примеров полно. Только лучше установить его локально, а то в онлайне дико трафик жрёт. Можно отсюда (там версия для XP и Server 2003, соответственно нет данных для Висты) или поискать посвежее, если Виста нужна.