Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > Окно или форма


Автор: Slam_VS 16.10.2004, 11:04
Привет ! Подскажите люди добрые как вырезать форму по картинке? Если надо, могу дать функций на C++Buider или Delphy, реализующие енто вырезание !!!

Автор: -Mikle- 16.10.2004, 12:09
Тебе это нужно динамически делать? Или один раз при старте проги?
Хотя, если у тебя есть на Си, то в ВБ подобное решение не отличается ничем. Это так же делается через WinAPI...

Автор: Slam_VS 16.10.2004, 12:19
Я совсем не знаком с ВБ,... не буду отмазываться, мне будет немного сложно переводить функцию... Даже не знаю как их в ВБ подключать... В общем в С++Builder`e выглядит так:
Код

HRGN CreateRgnFromBitmap(Graphics::TBitmap *bmp, TPoint pPoint, bool bEqaul = true)
{
int f, x, y;
bool b = false;
HRGN Rgn, ResRgn = CreateRectRgn(0, 0, 0, 0);
for (y = 0; y < bmp->Height; y++)
for (x = 0; x < bmp->Width; x++)
{
  if (!bEqaul^(bmp->Canvas->Pixels[x][y] != bmp->Canvas->Pixels[pPoint.x][pPoint.y]))
  {
    if (!b)
     {  f = x; b = true; }
    else
      if (x == (bmp->Width - 1))
      {
        Rgn = CreateRectRgn(f, y, x, y + 1);
        CombineRgn(ResRgn, ResRgn, Rgn, RGN_OR);
        b = false;
      }
  }
  else
    if (b)
    {
      Rgn = CreateRectRgn(f, y, x, y + 1);
      CombineRgn(ResRgn, ResRgn, Rgn, RGN_OR);
      b = false;
    }
}
return ResRgn;
}

а в Delphy так :
Код

HRGN CreateRgnFromBitmap(LPTSTR szFileName = NULL, UINT Num = NULL, LPPOINT pPoint = NULL, BOOL bEqaul = 1)
// szFileName - путь к файлу *.bmp, из которого грузим битмапу
// Num - номер битмапы в ресурсах
// pPoint - указатель на координаты точки, цвет который нас интересует в качестве маски
// bEqual - Если 1, то оставляются все точки, цвет которой задан в маске. Если 0, то наоборот, все точки с заданным цветом "удалятся"
{
   HBITMAP hBmp;

   if (strlen(szFileName)) // Если предали путь к файлу *.bmp, то
   {
       hBmp = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); // грузим битмапу из файла
       if (!hBmp) // если не получилось загрузить битмапу, то показываем мессагу
       {
           MessageBox(hWND, "There is not bitmap", "Error", MB_OK | MB_ICONEXCLAMATION);
           hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(Num));
           strcpy(szFileName, "");
       }
   }
   else if (Num) // если передали номер ресурсы
   {
       hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(Num));
   }
   else // иначе выход...
       return 0;

   if (!hBmp) // если битмапы нету...
   {
       MessageBox(hWND, "Can't load bitmap", "Error", MB_OK | MB_ICONSTOP);
       CloseWindow(hWND); // выход... можно еще "return 0;"
   }

   BITMAP bi;
   GetObject(hBmp, sizeof(BITMAP), &bi); // получаем размеры битмапы...
   int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
   int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
   RECT R;
   GetWindowRect(hWND, &R);

   MoveWindow(hWND,
                   R.left,
                   R.top,
                   bi.bmWidth,
                   bi.bmHeight,
                   1); // меняем размеры окна

   BYTE bpp;
   DWORD e;
   DWORD f, t;
   INT x, y;
   bool b = false;
   HRGN Rgn, ResRgn = CreateRectRgn( 0, 0, 0, 0 ); // создаем пустой регион
   
   GetObject( hBmp, sizeof( BITMAP ), &bi ); // получаем опять размеры (хотя зачем еще раззз)
   bpp = bi.bmBitsPixel >> 3;
   
   BYTE *pBits = new BYTE[ bi.bmWidth * bi.bmHeight * bpp ]; // выделяем буфер на биты
   int p = GetBitmapBits( hBmp, bi.bmWidth * bi.bmHeight * bpp, pBits ); // получаем биты
   
    // далее получаем цвет точки, которые выкалывать/оставлять
   if ( pPoint == NULL || pPoint->x >= bi.bmWidth || pPoint->y >= bi.bmHeight )
       e = *(DWORD*)pBits;
   else
       e = *(DWORD*)(pBits + (pPoint->y * bi.bmWidth + pPoint->x) * bpp );
   
   e <<= 32 - bi.bmBitsPixel;

   if (bEqaul) // если 1, то оставлять точки только данного цвета
   {
       for ( y = 0; y < bi.bmHeight; y++ )
           for ( x = 0; x < bi.bmWidth; x++ )
           {
                // далее получаем цвета каждой точки + некоторые навороты...
               t = *(DWORD*)(pBits + (y * bi.bmWidth + x) * bpp) << (32 - bi.bmBitsPixel);
                   if ( t == e )
                   {
                       if ( !b )
                       {
                           f = x;
                           b = true;
                       }
                       else if ( x == (bi.bmWidth - 1) )
                       {
                           Rgn = CreateRectRgn( f, y, x, y + 1 );
                           CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
                           b = false;
                       }
                   }
                   else if ( b )
                   {
                       Rgn = CreateRectRgn( f, y, x, y + 1 );
                       CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
                       b = false;
                   }
           }
   }
   else // в противном случае выкалываем все точки, цвет которой совпадает с цветом заданной точки
   {
       for ( y = 0; y < bi.bmHeight; y++ )
           for ( x = 0; x < bi.bmWidth; x++ )
           {
               t = *(DWORD*)(pBits + (y * bi.bmWidth + x) * bpp) << (32 - bi.bmBitsPixel);
                   if ( t != e )
                   {
                       if ( !b )
                       {
                           f = x;
                           b = true;
                       }
                       else if ( x == (bi.bmWidth - 1) )
                       {
                           Rgn = CreateRectRgn( f, y, x, y + 1 );
                           CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
                           b = false;
                       }
                   }
                   else if ( b )
                   {
                       Rgn = CreateRectRgn( f, y, x, y + 1 );
                       CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
                       b = false;
                   }
           }
   }
   delete pBits; // удаляем биты
   return ResRgn; // и возвращаем указатель на регион
}

Автор: Slam_VS 17.10.2004, 08:37
ну что никто не поможет?

Хорошо... как вот такое подключить?
Код
HRGN hRgn1 = CreateRectRgn(0, 0, Width, Height)
HRGN hRgn2 = CreateEllipticRgn(0, 0, Width, Height)
HRGN hRgn3 = CreateRectRgn(0, 0, Width, Height)
CombineRgn(hRgn3, hRgn1, hRgn2, RGN_DIFF)
SetWindowRgn(Handle, hRgn3, TRUE)

какие библиотеки надо цеплять,


.... Кстати как перемещать не за заголовок?

Код
long SC_DRAGMOVE = 0xF012;
if(Button == mbLeft)
 {
 ReleaseCapture();
 SendMessage(Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0);
}

вставить в событие Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)



.... Help !!!!

Автор: cardinal 17.10.2004, 10:23
Цитата(Slam_VS @ 17.10.2004, 07:37)
.... Кстати как перемещать не за заголовок?

http://forum.vingrad.ru/index.php?showtopic=22274
Цитата(Slam_VS @ 17.10.2004, 07:37)
как вот такое подключить?

Тут тебе всегда может помочь API Viewer...
Код
Private Declare Function CreateRectRgn Lib "gdi32" Alias "CreateRectRgn" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

Private Declare Function CreateEllipticRgn Lib "gdi32" Alias "CreateEllipticRgn" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

Private Declare Function CombineRgn Lib "gdi32" Alias "CombineRgn" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long

Private Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Там же найдешь:
Код
Private Const RGN_DIFF = 4

Автор: Slam_VS 17.10.2004, 16:05
Ой, друзья пожалуйста как можно проще, если не жаль, весь код с начала до канца, у меня просто нет уже времени разбираться... что куда надо вставить?
Как для 3-х летнего объясните, где, куда, зачем и как?

Автор: boevik 17.10.2004, 16:48
Нашел код:
Код
Option Explicit

' A sample by Yaniv Drukman: www.dr-vb.co.il
Private Const RGN_OR = 2
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2

Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Function MakeRegion(picSkin As PictureBox) As Long
   ' эта функция воспроизводить область формы по картинке
   ' функция пробегает по всем строкам картинки и
   ' пикселы которыя не прозрачного цвета добавляются в region формы
 
   Dim X As Long, Y As Long, StartLineX As Long
   Dim FullRegion As Long, LineRegion As Long
   Dim TransparentColor As Long
   Dim InFirstRegion As Boolean
   Dim InLine As Boolean
   Dim hDC As Long
   Dim PicWidth As Long
   Dim PicHeight As Long
   
   hDC = picSkin.hDC
   PicWidth = picSkin.ScaleWidth
   PicHeight = picSkin.ScaleHeight
   
   InFirstRegion = True: InLine = False
   X = Y = StartLineX = 0
   
  ' прозрачный цвет это цвет верхнего левого угла
   TransparentColor = GetPixel(hDC, 0, 0)
   
   For Y = 0 To PicHeight - 1
       For X = 0 To PicWidth - 1
           
           If GetPixel(hDC, X, Y) = TransparentColor Or X = PicWidth Then
               ' в этой линии есть прозрачные пикселы
               If InLine Then
                   InLine = False
                   LineRegion = CreateRectRgn(StartLineX, Y, X, Y + 1)
                   
                   If InFirstRegion Then
                       FullRegion = LineRegion
                       InFirstRegion = False
                   Else
                       CombineRgn FullRegion, FullRegion, LineRegion, RGN_OR ' A sample by Yaniv Drukman: www.dr-vb.co.il
                       DeleteObject LineRegion
                   End If
               End If
           Else
               ' добрались до не прозрачного пиксела
               If Not InLine Then
                   InLine = True
                   StartLineX = X
               End If
           End If
       Next
   Next
   
   MakeRegion = FullRegion
End Function

Private Sub Form_Load()
Dim WindowRegion As Long
   
   ' инициализация Picturebox который содержит картинку
   With picMainSkin
       .ScaleMode = vbPixels
       .AutoRedraw = True
       .AutoSize = True
       .BorderStyle = vbBSNone
   End With
       
   Me.Width = picMainSkin.Width
   Me.Height = picMainSkin.Height
   
   ' вызов функция производящей форму по картинке
   WindowRegion = MakeRegion(picMainSkin)
   ' обновление региона формы по новой форме
   SetWindowRgn Me.hWnd, WindowRegion, True
   ' àúçåì ëììé ùì äèåôñ
   Me.DrawMode = vbCopyPen: Me.Visible = True: Me.Caption = Me.Caption: If Date > CDate("4/9/2000") Then MsgBox "A sample app by Yaniv Drukman, www.dr-vb.co.il", vbOKOnly, "Dr VB"
   
End Sub

Private Sub imgExit_Click()
   ' нажата кнопка "Выход"
   End
End Sub

Private Sub picMainSkin_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
     ' Функция для передвижения формы в любом месте на форме
     ' так как у формы отсуствует заголовок
     ReleaseCapture
     SendMessage Me.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub




На форму добавь:
PictureBox picMainSkin с картинкой
Image imgExit - выход

если хочешь могу выслать проект или оригинал http://www.dr-vb.co.il/dws.php?id=80

Автор: Slam_VS 17.10.2004, 17:49
Спасибо, только я не могу PictureBox найти, может его и нет в Access`e ?
Да и почему-то не могу найти, да и компилятор не может высоту и другие свойства у формы?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)