ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Техніка програмування складних вікон в Visual Basic
         

     

    Інформатика, програмування

    Техніка програмування складних вікон в Visual Basic

    Вступ

    Mногіе з Вас напевно бачили в Windows програмах вікна нестандартної форми (круглі, трикутні і т.д.) і ставили собі питання: як мені зробити таке вікно? Якщо прочитати документацію по Visual Basic, то можна зробити висновок, що стандартні засоби мови не надають такої можливості. А що ж робити, якщо дуже хочеться? Тоді слід згадати, що в розпорядженні програміста на VB є ще й Windows API, який повинен нам у цьому допомогти.

    Теоретичні основи

    Для Спочатку давайте розберемося, як це можна зробити теоретично. З документації Windows видно, що кожне вікно в системі описується безліччю параметрів, з яких нас з Вами цікавить. Видима область вікна в системі, що створюється Visual Basic має вигляд прямокутника, але, в принципі, ніщо не заважає змінити форму цієї області. Дана область вікна описується за допомогою спеціального об'єкта, що називається Region. Регіон можна представити у вигляді поверхні, обмеженої координатами, описуваними кутові точки цієї області. Простіше кажучи, можна описати область будь-якої форми, а потім створити з неї, за допомогою спеціальних функцій, регіон та його до нужому нам вікна.

    Існує декілька функцій Windows API для створення регіонів, основними з яких є наступні:

    CombineRgn - Комбінує два регіони між собою

    CreateEllipticRgn - Створює регіон у вигляді еліпса або кола

    CreatePolygonRgn - Створює регіон у вигляді багатокутника

    CreateRectRgn - Створює прямокутний регіон

    CreateRoundRectRgn - Створює регіон із закругленими краями з прямокутної області

    SetWindowRgn - Прикріплює регіон до зазначеного вікна

    Я не буду приводити докладний опис цих функцій, так як його можна знайти в описі Win32 API. Крім цих функцій існують ще кілька функцій для роботи з регіонами, але нам вони не потрібні.

    Створення простих нестандартних вікон

    Тепер, коли нам відомі основні функції, для створення регіонів, ми можемо застосувати отримані знання з практики. Завантажте проект pTestRgn і уважно вивчіть його код. У цьому Проет, для зміни форми вікна на овальну, використовується всього три рядки коду та три функції Win32 API. Спочатку за допомогою CreateEllipticRgn створюється регіон, потім він прикріплюється до вікна і, нарешті, завершальна фаза видалення, яка стала непотрібною, створеного нами регіону. Якщо ж Ви не видалите непотрібний Вам більше об'єкт, то Windows, створивши регіон для Вас буде зберігати його у своїх і чекати подальших вказівок за його використання. Загалом, недобре виділену пам'ять, і наздожене Вас кара небесна, і затягнеться небо хмарами синіми, і буде страшний суд над усіма невіруючими: Короче код виглядає так:

    Private Sub cmbCreateOval_Click ()

    Dim lRgn As Long

    lRgn = CreateEllipticRgn (0, 0, Me.ScaleWidth / Screen.TwipsPerPixelX, _

    Me.ScaleHeight/Screen.TwipsPerPixelY)

    SetWindowRgn Me.hwnd, lRgn, True

    DeleteObject lRgn

    End Sub

    Так ж все просто, скажете Ви? Так, на перший погляд все дуже просто, але це тільки здається. Той приклад, який Ви тільки що бачили, майже не має практичного застосування в цих додатках Windows. Кому ж потрібно просто овальне вікно, яке до того ж жорстко задається на етапі програмування? А ось вікно, яке вільно могло б міняти свою форму цілком може знадобитися. Приклади? Будь ласка, WinAmp, Помічник в Microsoft Office та інші програми. Як же там все це реалізовано? Давайте розберемося з таким застосуванням регіонів.

    Створення складних нестандартних вікон

    Припустимо, що у нас є малюнок у форматі BMP, з якого потрібно зробити форму, а білий колір (наприклад) на ньому означає. Як же зробити форму? Дуже просто, потрібно взяти все пікселі на малюнку, створити з їх координат регіон і прикріпити його до потрібного нам вікна. Аналізувати пікселі можна GetPixel, ця функція за координатами повертає його колір. Давайте тепер напишемо такий алгоритм для аналізу BMP матриці. Я думаю, що такий алгоритм Вам відомий, і ми не будемо його докладно розбирати, зазначу лише, що аналіз проводиться порядково і Pixel-і додаються в регіон не поодинці, а групами порядково. Такий підхід сильно заощаджує ресурси процесора, виграш у продуктивності досягає 100%.

    Public Function lGetRegion (pic As PictureBox, lBackColor As Long) As Long

    Dim lRgn As Long

    Dim lSkinRgn As Long

    Dim lStart As Long

    Dim lX As Long

    Dim lY As Long

    Dim lHeight As Long

    Dim lWidth As Long

    'створюємо порожній регіон, з якого почнемо роботу

    lSkinRgn = CreateRectRgn (0, 0, 0, 0)

    With pic

    'підрахуємо розміри малюнка в Pixel

    lHeight =. Height/Screen.TwipsPerPixelY

    lWidth =. Width/Screen.TwipsPerPixelX

    For lX = 0 To lHeight - 1

    lY = 0

    Do While lY

    'шукаємо потрібний Pixel

    Do While lY

    lY = lY + 1

    Loop

    If lY

    lStart = lY

    Do While lY

    lY = lY + 1

    Loop

    If lY> lWidth Then lY = lWidth

    'потрібний Pixel знайдений, додамо його в регіон

    lRgn = CreateRectRgn (lStart, lX, lY, lX + 1)

    CombineRgn lSkinRgn, lSkinRgn, lRgn, RGN_OR

    DeleteObject lRgn

    End If

    Loop

    Next

    End With

    lGetRegion = lSkinRgn

    End Function

    Отже, для перевірки на практиці цього алгоритму завантажте приклад pTestRgnSkin і уважно вивчіть його код. У цьому проекті потрібний нам малюнок, для зручності,  у файлі ресурсів, крім того проект запускається процедурою Main, в якій і відбуваються всі перетворення. Спочатку завантажується форма, потім в PictureBox з ресурсів завантажується потрібний нам малюнок, далі викликається функція, яка створює регіон і, нарешті, завершальний етап - прикріплення регіону до потрібного нам вікна. Для зручності тут же викликається функція, поміщаються вікно, щоб воно у Вас на робочому столі Windows. Крім того, для нормальної роботи програми необхідно, щоб для PictureBox властивість AutoRedraw було встановлення в True, інакше нічого не вийде.

    Sub Main ()

    Dim lRgn As Long

    Load frmTestRgnSkin

    frmTestRgnSkin.pic.Picture = LoadResPicture (101, vbResBitmap)

    lRgn = lGetRegion (frmTestRgnSkin.pic, vbWhite)

    SetWindowRgn frmTestRgnSkin.hWnd, lRgn, True

    DeleteObject lRgn

    frmTestRgnSkin.Show

    SetFormPosition frmTestRgnSkin.hWnd, True

    End Sub

    Тепер можна запускати проект ... О, знайоме обличчя, скажіть Ви, це ж з Microsoft Office. Так, схожий, але не зовсім, рухається, а цей немає. Що ж потрібно зробити, щоб це вікно динамічно змінювало свою форму за малюнку, що в цей момент часу в PictureBox?

    Динамічне зміна форми вікна

    Існують програми в яких необхідно динамічно під час роботи змінювати форму вікна (наприклад анімований персонаж з Microsoft Office). Все це не дуже складно реалізувати, потрібно в подія PictureBox.Change додати наступний код:

    lRgn = LGetRegion (frmTestRgnSkin.pic, vbWhite)

    SetWindowRgn frmTestRgnSkin.hWnd, lRgn, True

    DeleteObject lRgn

    SetFormPosition frmTestRgnSkin.hWnd, True

    В принципі все готово, залишилося тільки додати код для зміни картинки на формі, і буде жити. У нашому прикладі змінювати малюнок будемо в Timer циклічно, тобто анімація буде безперервна, так простіше. Отже, додамо на форму Timer і помістимо невеликий код, який відповідає за зміни малюнка в PictureBox. Малюнків у файлі ресурсів десять штук, тому I має змінюватися від 101 до 110. Код зміни виглядає так:

    Static i As Long

    If i <101 Then i = 101

    If i> 110 Then i = 101

    frmAnimateForm.pic.Picture = LoadResPicture (i, vbResBitmap)

    i = I + 1

    Готово, можна запускати проект, і якщо Ви щасливий володар Pentium III або Athlon, то Вам посміхнеться удача, тому що буде рухатися. Але якщо Ваш процесор Pentium II і нижче, то комп'ютер не зможе виконувати необхідні розрахунки за потрібне нам час, тому що для плавної анімації необхідно (для нашого випадку) показувати близько 15 кадрів в секунду, а точніше кожні 80 мілісекунди по кадру і ще залишати час для інших завдань комп'ютера. Як ми бачимо наші алгоритми явно не тягнуть для таких завдань і призначені для  не потребують таких швидких змін форми вікна, так як, наприклад на Celeron 333 один кадр формується близько 100 мілісекунди. Що ж робити?

    Оптимізація алгоритму для швидкої анімації

    Аналіз роботи алгоритму показує, що найбільші витрати часу припадають на функцію GetPixel. Це відбувається тому, що аналіз картинки йде безпосередньо на екрані. Єдиний шлях збільшення швидкодії алгоритму, це перенесення аналізу в пам'ять комп'ютера і використання при цьому Win 32 API. Такі алгоритми існують, але це тема окремої розмови, скажу тільки, що для оптимізації роботи алгоритм пишеться окремо для кожної глибини кольору і при застосуванні такої схеми швидкодія збільшується майже в чотири рази і дозволяє робити практично будь-яку анімацію.

    Список літератури

    Для підготовки даної роботи були використані матеріали з сайту http://visualprogs.narod.ru/

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status