Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4

Модерирует : ShIvADeSt

ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988
В связи с тем, что все равно сабклассишь как и я свои кнопки в подобных приложениях вот код (взято из открытого проекта - там красивое определение каптурения кнопки). Но юзаю OwnerDraw стиль кнопки.

Код:
 
function ButtonProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  point         :TPoint;
  Rect          :TRect;
begin
  case Msg of
    WM_MOUSEMOVE:
      begin
        GetCursorPos(point);
        GetWindowRect(hwnd, rect);
        if PtInRect(rect, point) then begin
          if GetCapture <> hWnd then begin
            SetCapture(hWnd);
            MouseOver:=OverOK;
            InvalidateRect(hWnd,nil,FALSE);
          end;
        end else begin
          ReleaseCapture;
          MouseOver:=NotOver;
          InvalidateRect(hWnd,nil,FALSE);
        end;
      end;
      end;
  result := CallWindowProc(pointer(OldBtnProc), hWnd, Msg, wParam, lParam);
end;
 
 
procedure OnDrawItem(const DStr:PDRAWITEMSTRUCT);
var
     DC                 :HDC;
     Rect               :TRect;
     BtnText            Char;
     Focused            :boolean;
     holdFont,HTFont    :HFONT;
     Color              :TCOLORREF;
begin
   case DStr.CtlType of
   ODT_BUTTON:
   begin
      DC:=DStr.hDC;
      Rect:=DStr.rcItem;
      case DStr.CtlID of
      BTN_OK: begin
          BtnText:=PChar(GetProp(DStr.hWndItem,'Caption'));
          if (DStr.itemState and ODS_FOCUS)<>0 then Focused:=True else Focused:=False;
           if (DStr.itemState and ODS_SELECTED)<>0 then
            DrawButtonDown(DC,Rect.Left,Rect.Top,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top,Focused,BtnText)
          else DrawButton(DC,Rect.Left,Rect.Top,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top,Focused,BtnText);
          if (MouseOver=OverOK) and NOT ((DStr.itemState and ODS_SELECTED)<>0) then
             DrawButtonUp(DC,Rect.Left,Rect.Top,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top,Focused,BtnText);
         end;
      end;
    end;
  end;
end;
 
 
WM_DRAWITEM: OnDrawItem(PDRAWITEMSTRUCT(lParam));
 
 

 
пользуйся.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:06 01-12-2008
Yozj



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
shadow user777
Можно конечно, садишься, открываешь проект в С++Builder, содаешь проект той же структуры в Delphi и по строчечкам аккуратно переводишь с С++ на Delphi
Или ты рассчитываешь, что существует универсальный автоконвертатор из Си в Delphi?
 
Добавлено:
yegorovpavel
Смотри события:
OnClickAxis
OnClickBackground
OnCLickLegend
OnClickSeries
 
Каждый обрабатывает свой клик, но все имеют координаты X, Y - координаты отображения.
Чтобы перевести в координаты нужного графика смотри хелп по функциям:
XScreenToValue
YScreenToValue
и им подобные.
 
Например, я на OnClickBackground получаю координаты в терминах графика следующим образом:

Код:
 
  Sender.Title.Text.Add('Series 0 X: '+FloatToStr(Sender.Series[0].XScreenToValue(X)) + ', Y: '+FloatToStr(Sender.Series[0].YScreenToValue(Y)));
 

Всего записей: 125 | Зарегистр. 01-12-2004 | Отправлено: 11:29 01-12-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
Блин, немного непонятные некоторые ньюансы у Вашего кода. Допустим TRUE или FALSE принимает. Но надо понимать OverOK у Вас в WM_MOUSEMOVE TRUE принимает, а NotOver - FALSE? Я не гуру, нам бы простым любителям-программистам что-нибудь попроще.
И еще у Вас код if (DStr.itemState and ODS_FOCUS)<>0 then Focused:=True else Focused:=False;
Используется переменная Focused для DrawButton*. Вот тут я не знаю к чему мне результаты этого Focused, а ведь (DStr.itemState and ODS_FOCUS)<>0 поди тут тоже важно.
 
Изменил на такой код, немного переработав:
Далее...
 
Но... пока непонятно, как сделать такой эффект: Курсор навели на кнопку, подождали, нажали кнопку, должна измениться картинка у кнопки с наведенной на нажатую. Сделал вроде как через ODS_FOCUS проверку, но не выходит ничего. Хм, непонятен этот момент.
И все-таки хочется чтобы Вы скачали проект по ссылке и посмотрели. А то все слова слова, а тут на деле сразу. И вот хотел узнать, Вы определяетев обоработчике еще и тип контрола через ODT_BUTTON. Я вроде как без него сделал, вроде картинки рисуются на кнопке. Стоит ли так выполнять отрисовку?
 
Спасибо.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 13:43 01-12-2008
shadow user777



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Yozj
Так как в програмировании я почти 0, конечно хочется автоконвертер
Ладно, билдер поставил, щас начну сражатся
 
Кстати для начинающих, хочу порекомендовать продукт Hiasm http://hiasm.com/index.html
В нем можно сделать почти ВСЕ. И разбиратся в программировании не обязательно. Все делается в визуальном редакторе.
Аналог Дэльфи и прочих билдеров.

Всего записей: 1449 | Зарегистр. 31-07-2005 | Отправлено: 14:35 01-12-2008 | Исправлено: shadow user777, 14:43 01-12-2008
Yozj



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
shadow user777
Да, мне нравится эта программа, отлично подходит если не надо привязываться к языку и надо быстро что-то сделать.
Ошибка в ссылке: http://hiasm.com/index.html

Всего записей: 125 | Зарегистр. 01-12-2004 | Отправлено: 14:41 01-12-2008
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
HiAsm штука действительно интересная, но для тех, кто умеет программировать, почти бесполезная. По крайней мере я так и не смог найти ему применение, когда разбирался с ним.

Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 20:30 01-12-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988
В том то и дело, что твои исходники я скачал и посмотрел. Увидел много похожего с моими сорсами, чтобы не искать ошибки у тебя - предложил тебе свои. В общем, несколько советов. Если тебе надо использовать переменные внутри только одной процедуры (функции), то объявляй их внутри этой процедуры. Никогда так не делай

Код:
 
procedure PaintImageFileButton(DC : HDC; RtBtn : TRect; szPathFile : WideString);
begin
  CompDC := CreateCompatibleDC(0);
  NewBmp := LoadImageW(hInstance, PWideChar(szPathFile), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE or LR_LOADFROMFILE);
  OldBmp := SelectObject(CompDC, NewBmp);
  BitBlt(PS.hDC, 0, 0, RtBtn.Right - RtBtn.Left, RtBtn.Bottom - RtBtn.Top, CompDC, 0, 0, SRCCOPY);
  SelectObject(CompDC, OldBmp);
  DeleteDC(CompDC);
  DeleteObject(NewBmp);
end;
 

Для чего ты передаешь в процедуру указатель контекста, если рисуешь в итоге на другом. Я слегонца офигел, когда мой код не заработал как должен был, но когда глянул глобальные переменные - офигел еще больше В общем вот готовый пример, правда кнопку я таки сделал OWNERDRAW
Подробнее...
 
Добавлено:
Maks150988

Цитата:
И все-таки хочется чтобы Вы скачали проект по ссылке и посмотрели. А то все слова слова, а тут на деле сразу. И вот хотел узнать, Вы определяетев обоработчике еще и тип контрола через ODT_BUTTON. Я вроде как без него сделал, вроде картинки рисуются на кнопке. Стоит ли так выполнять отрисовку?  

В принципе не надо, если исходить из имен ресурсов, но к примеру у меня будет 20 кнопок с разными названиями, но одинакового поведения, тогда проще будет исходить из типа ресурса, а в обработчике отрисовки просто получать заголовки кнопок, так как только они отличаются.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:44 02-12-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
Спасибо. А как тогда поступать, если хочется поболее кнопок разрисовать. Понимаю что глупо, но сделал вот так: Подробнее
 
Нужно в цикле как-нибудь пронумеровать DrawCloseButton для каждой кнопки или можно одну эту функцию использовать для всех кнопок или просто OldBtnProc в массив засунуть и для каждой кнопки засабклассить? А то сейчас, например, навели на кнопку курсор и нажали, цвет у другой сменился на активный, хотя не должно так быть.
Хочется универсального решения с минимальным кодом.

Цитата:
Для чего ты передаешь в процедуру указатель контекста, если рисуешь в итоге на другом.

То есть? Имеется ввиду PaintImageFileButton? Если да, то там рисуется на DC, а это уже может быть и PDRAWITEMSTRUCT и TPaintStruct. Вроде универсально...

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 09:58 02-12-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988

Цитата:
То есть? Имеется ввиду PaintImageFileButton? Если да, то там рисуется на DC, а это уже может быть и PDRAWITEMSTRUCT и TPaintStruct. Вроде универсально...

Посмотри что передаешь и на чем рисуешь. Передаешь
Цитата:
PaintImageFileButton(DC : HDC;

а рисуешь
Цитата:
BitBlt(PS.hDC,
. А все из-за того, что очень много глобальных переменных, поэтому не ругалось.

Цитата:
Хочется универсального решения с минимальным кодом.  

Сам такое хочу найти Все что нашел в инете - это создавать класс кнопок, тогда у каждой кнопки будет свой MouseOver и соответственно только нужная кнопка будет отрисовываться.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 11:08 02-12-2008
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
А не подскажете, у меня тут программа написана вроде на i86, раньше она работала. она вызывает int 10 c ax 80 наверное переключает текстовый режим, на тот же самый текстовый режим, в результате чего консоль разворачивается на весь экран. А сейчас она не реботает. Незнаю почему, может можно как-то исправить прогу?

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 14:05 02-12-2008
Yozj



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
Под какой ОС программа?
По моему Windows XP, Vista механизм прерываний полностью блокируют.

Всего записей: 125 | Зарегистр. 01-12-2004 | Отправлено: 14:17 02-12-2008
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Yozj
А под Windows 98 нормально работает. Понятно же что Virtual PC на домашнем Vista тоже синий экран может показывать. Как вот он это делает? И главно потом Alt-Tab не работает почему-то.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 15:48 02-12-2008
Yozj



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
Так Win98 - совсем другая архитектура ядра и понятия безопасности. А как обрабатывают  такие прерывания эмуляторы - вопрос к ним, далеко не факт что под ними это возможно.

Всего записей: 125 | Зарегистр. 01-12-2004 | Отправлено: 16:22 02-12-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
DosBox -- наше всё...
www.dosbox.com

Всего записей: 24120 | Зарегистр. 06-12-2002 | Отправлено: 17:30 02-12-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
А у Вас случайно нет кода, как отрегионить кнопку по определенному цвету? И вот немного не понимаю как сделать такое. Имеем битмап, цвет для прозрачности фуксия, загружаем битмап и по этому цвету регионим кнопку, сама кнопка отображается нормально как надо - ее место в которое с регионами отцапано не "закрашивает" картинку диалога.
Сделал пока так http://webdrive.avtograd.ru/Download/Explorer/temp/hbutton.zip но это не выход красить задний неиспользуемый якобы фон самого битмапа кнопки. Ведь можно также фуксией закрасить и тогда квадратная кнопка будет в своей красе с прозрачностью что не гуд.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 20:50 02-12-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988
Посмотри тут http://jhekasoft.narod.ru/rgn_btn.htm

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:43 03-12-2008
sadasaf



BANNED
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Огромная просьба, помогите решить:  
Постановка задачи:  
1. Номер минимального по модулю элемента массива.  
2. Сумму модулей элементов массива, расположенных после первого отрица-тельного элемента.  
Сжать массив, удалив из него все элементы, величина которых находится в интервале [a,b]. Освободившиеся в конце массива элементы заполнить нулями




типовые задачи по паскалю (а тут голимый паскаль) вверху в прибитую тему

Всего записей: 216 | Зарегистр. 18-08-2008 | Отправлено: 02:45 03-12-2008 | Исправлено: ShIvADeSt, 06:55 03-12-2008
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akaGM
Спасибо, скачал с исходниками, правда они на Си, а есть ли решение для Delphi Console Project? Вижу, что очень мощное средство, но пока проверить не могу, нет админских привелегий. А запуск dosshell.exe требует, кстати, нельзя что ли без admin?
 
Был бы благодарен за уточнения где смотреть...
Удачи.
 
Добавлено:
Yozj
Да не факт, наверное придётся делать по разному для Vista и Windows 98.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 08:09 03-12-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
Блин, да там VCL Я плохо разбираюсь в некоторых конструкциях кода - всякие TBitmap и подобные Image.Canvas.Pixels[0, y] смущают. Остальное впринципе не проблема под Апи переделать.
 
Значит, сделал вот так, подобие скина Винампа с кнопками Медиа плейера Виндовс. Вроде для примера смотрится очень даже ничего.
http://webdrive.avtograd.ru/Download/Explorer/temp/skincore.zip
Только есть вопросик. Почему не работают пункты системного контекстного меню - WM_CONTEXTMENU? Эм, без понятия если честно. False возвращаю, а толку... и еще одна особенность. После запуска программки если вызвать это меню - оно как-бы не поиницализировано чтоли - пункты без изменения и все активны. А вот если подвигать диалог программы - пункты принимают впринципе нормальный вид - пункт закрытия выделяется жирным шрифтом и другие пункты неактивны становятся. Но если жать на пункты - не работают. В чем собственно дело?
 
А функцию переделал так:
 

Код:
function BitmapToRgn(szPathFile: WideString): HRGN;
var
  Bitmap: HBITMAP;
  BmpInfo : TBitmapInfo;
  TmpRgn: HRGN;
  x, y: integer;
  ConsecutivePixels: integer;
  TranparentColor: COLORREF; //Прозрачный цвет
  CurrentPixel: COLORREF;
  CurrentColor: COLORREF;
  MskBmpDC:HDC;
begin
 
  Bitmap := LoadImageW(hInstance, PWideChar(szPathFile), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  GetObject(Bitmap, SizeOf(BmpInfo), @BmpInfo);
  Result := CreateRectRgn(0, 0, BmpInfo.bmiHeader.biWidth, BmpInfo.bmiHeader.biHeight);
  if (BmpInfo.bmiHeader.biWidth = 0) or (BmpInfo.bmiHeader.biHeight = 0) then
    exit;
  MskBmpDC := CreateCompatibleDC(0);
  SelectObject(MskBmpDC, Bitmap);
  TranparentColor := GetPixel(MskBmpDC, x, y);
  for y := 0 to BmpInfo.bmiHeader.biHeight - 1 do
    begin
      CurrentColor := GetPixel(MskBmpDC,0, y);
      ConsecutivePixels := 1;
      for x := 0 to BmpInfo.bmiHeader.biWidth - 1 do
      begin
        CurrentPixel := GetPixel(MskBmpDC,x, y);
        if CurrentColor = CurrentPixel then
          inc(ConsecutivePixels)
        else
          begin
            if CurrentColor = TranparentColor then
              begin
                TmpRgn := CreateRectRgn(x - ConsecutivePixels, y, x, y + 1);
                CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
                DeleteObject(TmpRgn);
              end;
            CurrentColor := CurrentPixel;
            ConsecutivePixels := 1;
          end;
      end;
    end;
  DeleteObject(Bitmap);
  DeleteDC(MskBmpDC);
  if (CurrentColor = TranparentColor) and (ConsecutivePixels > 0) then
    begin
      TmpRgn := CreateRectRgn(x - ConsecutivePixels, y, x, y + 1);
      CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
      DeleteObject(TmpRgn);
    end;
end;

Но походу неправильно переделал. Немного непонятно как часть кода перевести.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 22:53 03-12-2008 | Исправлено: Maks150988, 00:00 04-12-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988
Вот мой код, в свое время сам переводил с ВБ на Дельфи битмапку в регион

Код:
 
function MakeRegion(DC:HDC):HRGN;
var
     x,y,StartLineX             :integer;
     FullRegion,LineRegion      :HRGN;
     TransparentColor           :COLORREF;
     InFirstRegion,_InLine      :Boolean;
     PicWidth,PicHeight         :integer;
begin
     DC:=DC;
     PicWidth:=96;
     PicHeight:=80;
     InFirstRegion:=True;
     _InLine:=False;
     StartLineX:=0;
     TransparentColor:=GetPixel(DC,0,0);
     for Y:=0 to PicHeight-1 do
        for X:=0 to PicWidth-1 do
            if (GetPixel(DC, X, Y)=TransparentColor)then begin
                if _InLine then begin
                    _InLine:=False;
                    LineRegion:=CreateRectRgn(StartLineX,Y,X,Y+1);
                    if InFirstRegion then begin
                        FullRegion:=LineRegion;
                        InFirstRegion:=False;
                       end
                      else begin
                        CombineRgn(FullRegion, FullRegion, LineRegion, RGN_OR);
                        DeleteObject(LineRegion);
                       end;
                   end
               end
           else
                If NOT _InLine then begin
                    _InLine:=True;
                    StartLineX:=X;
                   end;
    Result:=FullRegion;
end;
 


----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 04:37 04-12-2008
   

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4
ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru