Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: api контролы [c++ builder]  (Прочитано 19292 раз)
0 Пользователей и 1 Гость смотрят эту тему.
race1
Гость
« : 03-01-2005 10:28 » 

задумал делать несколько классов, типа кнопки, лейбла и т.п., используя только api. создавать эти контролы я вроде умею (createwindowex и далее), но как назначить wndproc для каждого контрола в отдельности, что бы обрабатывать сообщения. или нужно сообщения от дочерних контролов обрабатывать в wndproc главной формы?
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 03-01-2005 12:44 » 

wndproc одна на все контролы одного класса.  Она задаётся в вызове RegisterClass

Сообщения от детей обрабатывает родитель.  соответственно, в оконной функции родителя надо предусмотреть, что будут приходить сообщения от детей.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
race1
Гость
« Ответ #2 : 03-01-2005 14:27 » 

но есть ф-я SetWindowLong, где можно указать в т.ч. и wndproc для HANDLE'а. или изменится wndproc для всех, например, кнопочек? Улыбаюсь
« Последнее редактирование: 20-12-2007 19:04 от Алексей1153++ » Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 03-01-2005 16:08 » 

Изменится только для одного окна.

Чтобы для всех кнопочек, то надо найти все кнопочки (хендлы к их окнам) и поменять через SetWindowLongPtr
Если кнопочки самописные, то для них нужную функцию пропиши в класс при регистрации класса.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
race1
Гость
« Ответ #4 : 07-01-2005 15:06 » 

но вы говорите что для одного класса одна wndproc. получается, если я опеределю через setwindowlong wndproc, то только для указанного окна, а не для всего класса? и получу в итоге wndproc как бы для стд. кнопки, ибо при создании кнопки указывался стд класс @button"
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #5 : 07-01-2005 15:10 » 

race1, чего конкретно ты хочешь.
Обрабатывать сообщения от кнопок типа WM_MOUSEMOVE и т.п.
или просто получать сообщениея, что кнопка нажата?

В первом случае тебе надо получить хендл окна кнопки и поменять windowproc на свою.
Во втором случае все делается в windowproc основного окна, в котором находится кнопка.
Записан

Megabyte be with you!
race1
Гость
« Ответ #6 : 09-01-2005 13:38 » 

я бы хотел сделать стд. кнопку на апи, и рисовать её. она бы мне присылала сообщения что её состояние изменилось, что её нужно перерисовать и т.д. сейчас я наследуюсь от tcustomcontrol и очень много приходится симулировать. а так кнопка сама бы отвечала за своё поведение, а я бы её просто рисовал и больше не заморачивался
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #7 : 09-01-2005 14:21 » 

Я не уверен - но насколько я понимаю все что нужно кнопке и все ее слообщения будут атвоматом проходить если наследоваться от TBottom. Проблема в том, что я не знаю как организованы такие контроли в Борланде.
В Майкрософте наследуясь от класса кнопки и создавая свою мне достаточно отрабатывать мои личные навароты - остальное компронент сделает сам.

Но во твоем вопросе есть одна загвоздка...

Ты пишешь что тебе надо
Цитата
стд. кнопку на апи
А каким боком контроли борланда относятся к АПИ. АПИ - это чисто майкрософтовская отработка.
Рисуя на нем ты не можешь использовать никаких Борландовских настроек!!!
Записан

А птичку нашу прошу не обижать!!!
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #8 : 09-01-2005 18:25 » 

Как у тебя кнопка меняет состояния?

А в общем случае тебе надо перехватывать WM_PAINT сообщение и рисовать свою кнопку
Записан

Megabyte be with you!
race1
Гость
« Ответ #9 : 12-01-2005 06:16 » 

посмотрев на сорцы vcl'я и почитав msdn я пришёл к выводу что если я хочу кастом-пеинт кнопку на базе vcl, придётся симулировать кнопку - определять нажатие, отпускание и т.д. а в мсдн я увидел что при изменении статуса кнопки приходит месседж где говорится в каком положении сейчас кнопка... хотя сообщение должно приходить родителю кнопочки...

Цитата
А каким боком контроли борланда относятся к АПИ. АПИ - это чисто майкрософтовская отработка.
Рисуя на нем ты не можешь использовать никаких Борландовских настроек!!!

я думал что создании api кнопочки будет наиболее просытм решением... кроме того пригодилось бы в дальнейшем, ибо возможно придётся все контролы писать на api
« Последнее редактирование: 20-12-2007 19:08 от Алексей1153++ » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #10 : 12-01-2005 19:52 » 

race1, в создании компоненты в чистом API нет ничего сложного. Просто там нужно учитывать некоторые приколы, которые маскируются всеми надстройками. На каком уровне твои знания WinAPI?
Выкладываю Код компоненты кнопка. Она конечно недоработана (В свое время я ее делал для узкой задачи)
Button.h,
Код:
//---------------------------------------------------------------------------
#ifndef button_H
#define button_H

const char FAR *szButtonName = "C_Button";
const UINT WM_SETACTION = WM_USER+2;


typedef struct _ButtonStr {
   HBRUSH   brBkGnd;
   COLORREF RGBBkGnd;
   bool     Drug;
   bool     Down;
   bool     Cup;
   int      Action;
   } ButtonStr;

ButtonStr *Button_GetData(const HWND hwnd);
ButtonStr *Button_NewData(const HWND hwnd);

bool Button_Register(HINSTANCE);
LRESULT CALLBACK Button_WndProc(HWND, UINT, WPARAM, LPARAM);

bool Button_onCreate(HWND hWin, CREATESTRUCT FAR* lpCreateStruct);
void Button_onPaint(HWND);
void Button_OnDestroy(HWND hwnd);
void Button_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
void Button_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
void Button_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
bool Button_OnEraseBkgnd(HWND hwnd, HDC hdc);
void Button_Paint(HWND,HDC);
//---------------------------------------------------------------------------
#endif

Button.cpp,
Код:
//---------------------------------------------------------------------------
#include <windows.h>
#include <windowsx.h>

#include "button.h"
#include "Basic.cpp"

LRESULT CALLBACK Button_WndProc(HWND hWindow, UINT Message,
                         WPARAM wParam, LPARAM lParam)
{
  ButtonStr *bst=Button_GetData(hWindow);
   switch (Message)
      {
       HANDLE_MSG(hWindow, WM_DESTROY,     Button_OnDestroy);
       HANDLE_MSG(hWindow, WM_CREATE,      Button_onCreate);
       HANDLE_MSG(hWindow, WM_PAINT,       Button_onPaint);
       HANDLE_MSG(hWindow, WM_MOUSEMOVE,   Button_OnMouseMove);
       HANDLE_MSG(hWindow, WM_LBUTTONDOWN, Button_OnLButtonDown);
       HANDLE_MSG(hWindow, WM_LBUTTONUP,   Button_OnLButtonUp);
       HANDLE_MSG(hWindow, WM_ERASEBKGND,  Button_OnEraseBkgnd);
        case WM_SETACTION :
          bst->Action=wParam;
          break;
       default:
          return DefWindowProc(hWindow, Message, wParam, lParam);
      }
}
bool Button_Register(HINSTANCE hInst)
{
   WNDCLASS wc;

   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = (WNDPROC) Button_WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = sizeof(ButtonStr);
   wc.hInstance     = hInst;
   wc.hIcon         = 0;
   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = szButtonName;

   return (RegisterClass(&wc) !=0);

}
void Button_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
 ButtonStr *bst=Button_GetData(hwnd);
 POINT pt;
 pt.x=x;
 pt.y=y;
 RECT r ;
 SetRectEmpty(&r);
 GetClientRect(hwnd, &r);
 bst->Drug=PtInRect(&r,pt);
 if (bst->Drug | bst->Down)
    {
     if (!bst->Cup)
        {
         SetCapture(hwnd);
         HDC dc=GetDC(hwnd);
         Button_OnEraseBkgnd(hwnd, dc);
         Button_Paint(hwnd,dc);
         ReleaseDC(hwnd,dc);
         bst->Cup=true;
        }
    }
 else
    {
     if (bst->Cup)
        {
         ReleaseCapture();
         HDC dc=GetDC(hwnd);
         Button_OnEraseBkgnd(hwnd, dc);
         Button_Paint(hwnd,dc);
         ReleaseDC(hwnd,dc);
         bst->Cup=false;
        }
    }
 }

void Button_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
 ButtonStr *bst=Button_GetData(hwnd);
 bst->Down=true;
 HDC dc=GetDC(hwnd);
 Button_OnEraseBkgnd(hwnd, dc);
 Button_Paint(hwnd,dc);
 ReleaseDC(hwnd,dc);
}

void Button_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
 ButtonStr *bst=Button_GetData(hwnd);
 bst->Down=false;
 HDC dc=GetDC(hwnd);
 Button_OnEraseBkgnd(hwnd, dc);
 Button_Paint(hwnd,dc);
 ReleaseDC(hwnd,dc);
 if (bst->Drug)
    {
    if (bst->Action !=0)
       {
         ReleaseCapture();
         bst->Drug=false;
         bst->Cup=false;
         HDC dc=GetDC(hwnd);
         Button_OnEraseBkgnd(hwnd, dc);
         Button_Paint(hwnd,dc);
         ReleaseDC(hwnd,dc);


       PostMessage((HWND) GetWindowLong(hwnd,GWL_HWNDPARENT),WM_COMMAND,bst->Action, (LONG) hwnd);
       }
    }
}

void Button_OnDestroy(HWND hwnd)
{
ButtonStr *Temp = (ButtonStr *) SetWindowLong(hwnd, GWL_USERDATA, 0);
if (Temp->brBkGnd != NULL) DeleteObject(Temp->brBkGnd);
if (Temp !=0) delete Temp;
}

bool Button_onCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
{
ButtonStr *bst=Button_NewData(hwnd);
if (bst==0) return false;
bst->RGBBkGnd=RGB(127,127,127);
bst->brBkGnd=CreateSolidBrush(bst->RGBBkGnd);
bst->Drug=false;
bst->Down=false;
bst->Action=0;
return true;
}

void Button_onPaint(HWND hwnd)
{
   PAINTSTRUCT PaintStruct;

   HDC dc = BeginPaint(hwnd,&PaintStruct);
   Button_Paint(hwnd,dc);
   EndPaint(hwnd, &PaintStruct);
}

bool Button_OnEraseBkgnd(HWND hwnd, HDC hdc)
{
   RECT r;
   SetRectEmpty(&r);
   ButtonStr *bst=Button_GetData(hwnd);

   GetClientRect(hwnd, &r);
   FillRect(hdc,&r,bst->brBkGnd);
   return true;
}

ButtonStr *Button_GetData(const HWND hwnd)
{
return (ButtonStr *) GetWindowLong(hwnd,GWL_USERDATA);
}

ButtonStr *Button_NewData(const HWND hwnd)
{
ButtonStr *Bst = new ButtonStr;
ButtonStr *Temp = (ButtonStr *) SetWindowLong(hwnd, GWL_USERDATA, (LONG) Bst);
if (Temp !=0) delete Temp;
return Bst;
}
void Button_Paint(HWND hwnd,HDC dc)
{
   int Size=GetWindowTextLength(hwnd);
   ButtonStr *bst=Button_GetData(hwnd);
   Size++;
   char *Text=new char[Size];
   GetWindowText(hwnd,Text,Size);
   Text[Size-1]=0;
   RECT r;
   SetRectEmpty(&r);
   GetClientRect(hwnd, &r);
   SetBkMode(dc,TRANSPARENT);
   if (bst->Drug | bst->Down)
      {
      if (bst->Down)
          Frame3D(dc, &r, RGB(76,76,76),RGB(255,255,255), 2);
      else
          Frame3D(dc, &r, RGB(255,255,255), RGB(76,76,76),2);
      }

   SetTextColor(dc,RGB(0,0,0));
   DrawText(dc,Text,Size-1, &r,  DT_VCENTER | DT_SINGLELINE);
   r.left--;
   r.top--;
   r.right--;
   r.bottom--;
   SetTextColor(dc,RGB(255,255,255));
   DrawText(dc,Text,Size-1, &r,  DT_VCENTER | DT_SINGLELINE);


   delete Text;
}
//---------------------------------------------------------------------------

Перед тем как использовать эту компоненту надо зарегистрировать ее с помошью функции Button_Register.
Потом создаеш обычное окно с помошью функции CreateWindow. Где в параметре pClassName указываеш "C_Button".
« Последнее редактирование: 12-01-2005 20:13 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
race1
Гость
« Ответ #11 : 14-01-2005 10:42 » 

спасибо за пример. я собсно и так знаю что это несложно... кстати, а что за Frame3D, он  меня есть только в Extctrls, но там для канвы (первый параметр - TCanvas)
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 14-01-2005 15:47 » 

Эта функция рисует трехмерную рамку. Я её честно выдрал из VCL. Просто нехотелось ташить все библиотеки и переделал под мои реали. Она у меня сидит в моей обшей библиотеке Basic.cpp. Так что можеш ее сам нарисовать.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 21-04-2006 20:26 » 

(комент)

кнопку Финча - в будущую галерею самопала
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines