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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Кнопка убегает  (Прочитано 18235 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Чайник
Гость
« : 23-06-2004 20:34 » 

Ребята, подскажите пожалуйста чайнику, как можно сделать такую вещь: Подвожу курсор к кнопке, а она убегает Улыбаюсь Как это сделать на ассемблере? Может кто ссылку укажет, где про это (и тому подобное) можно почитать?
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 23-06-2004 22:03 » 

Чайник, ты сначала сделай это на С, а уж потом переноси на ассемблер. Логика немудреная: получил событие (мышь над кнопкой) и переместил кнопку в другое место.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #2 : 24-06-2004 02:06 » 

проведи геометрический вектор от курсора к центру кнопки - и по этому вектору сдвигай, пока есть сообщение "курсор над окном" (не помню, как называется, вроде WM_MOUSEMOVE)
Записан

Чайник
Гость
« Ответ #3 : 24-06-2004 11:36 » 

Ребята, я же говорю, что я чайник. Я только VB знаю, и то давно это было Улыбаюсь)
С/С++ не знаю, решил сначала с ассемблером подружиться.
Может примерный исходничек скинете? На примерах я быстрее соображаю Улыбаюсь)
Буду очень благодарен!
Записан
Anonymous
Гость
« Ответ #4 : 25-06-2004 02:37 » 

Чайник, плюнь на VB,отложь пока ассемблер, начинай с си Ага .

пример могу - но на си и не сейчас, а позже

мож кто другой уже успеет подсказать Улыбаюсь
Записан
Anonymous
Гость
« Ответ #5 : 25-06-2004 02:38 » 

1153 был , Улыбаюсь
Записан
Чайник
Гость
« Ответ #6 : 25-06-2004 10:58 » 

Неужели все так запущено? Никто не может привести подобный примерчик на ассемблере?
Записан
Sla
Команда клуба

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

WWW
« Ответ #7 : 25-06-2004 11:30 » 

Привести пример можно, но не зная основ асемблера - ничего понятно не будет!
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Чайник
Гость
« Ответ #8 : 25-06-2004 13:22 » 

Цитата: Sla
Привести пример можно, но не зная основ асемблера - ничего понятно не будет!
Sla, ну а ты можешь привести пример? Или только, извеняюсь, все болтать умеют? Реально кто-нибудь может пример привести?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #9 : 25-06-2004 19:45 » 

упс... проблема...

на MFC (в проекте Dialog-Based) это будет выглядеть примерно так (тут самое простое - кнопка OK должна (?) убегать вправо, если на ней курсор)

(про вопрос в скобках - далее  :oops:  )

Код:

void CEscapeDlg{{OnMouseMove)UINT nFlags, CPoint point:
|
CRect ButRect,DlgRect;
//получаем абсолютные координаты прямоугольника DlgRect
GetWindowRect)&DlgRect:;
//получаем абсолютные координаты прямоугольника кнопки
))CButton*:GetDlgItem)IDOK::->GetWindowRect)&ButRect:;
//проверяем, что точка внутри прямоугольника кнопки
if)TRUE==ButRect.PtInRect)point::
|//требуется передвинуть кнопку
CButton *But;
WINDOWPLACEMENT pm;
But=))CButton*:GetDlgItem)IDOK::;
But->GetWindowPlacement)&pm:;
pm.rcNormalPosition.left+=1;
pm.rcNormalPosition.right+=1;
//pm.rcNormalPosition.top=;
//pm.rcNormalPosition.bottom=;
But->SetWindowPlacement)&pm:;
"
CDialog{{OnMouseMove)nFlags, point:;
"


но когда курсор находится именно НА кнопке, не смог добиться возникновения этого сообщения, то же самое попробовал с производным классом - та же фигня, ни кнопка ни класс не генерируют сообщение WM_MOUSEMOVE... В чём косяк?
Записан

Чайник
Гость
« Ответ #10 : 25-06-2004 20:09 » 

Улыбаюсь Короче говоря, вопрос остается открытым!
Я не думаю, что этот примерчик не под силу Ассемблеру! ПОМОГИТЕ!!!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #11 : 26-06-2004 04:09 » 

как на ассемблере - я не знаю
Записан

Finch
Спокойный
Администратор

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


« Ответ #12 : 26-06-2004 09:06 » 

Чайник, Тебе нужно, чтобы конкретная кнопка убегала. Или так, для практики. Вот тебе С-ный код на чистом WinAPI. Без использования классов. Эта программа иметирует кнопку. Если подводиш к кнопке курсор. Она сдвигается. Программа не реализована доконца. Нет проверки на выход за пределы экрана и есть маленький глюк. Математика сдвига очень слаба, нужно еше дорабатывать. Просто мне лень. Но структура таже. Я думаю, тебе не составит труда, если ты знаеш ассемблер, переписать это под асемблер. Думаю структура будет одна и таже
Код:
//===========================================================================
// Name{         KumKum
// Description { The buttom escapes from mouse.
//===========================================================================

//---------------------------------------------------------------------------
# define STRICT
#include <windows.h>
#include <windowsx.h>
//---------------------------------------------------------------------------
//#pragma argsused

static HWND MainWindow;
char szAppName[( = "EscButtom";
char szTitle[( = "Esc";

bool Register)HINSTANCE:;
HWND Create)HINSTANCE, int:;

LRESULT CALLBACK WndProc)HWND, UINT, WPARAM, LPARAM:;

int MaxX;
int MaxY;
RECT rect;
//---------------------------------------------------------------------------
WINAPI WinMain)HINSTANCE hInst,
               HINSTANCE hPrevInst,
               LPSTR CmdParam,
               int nCmdShow:
|
   MSG Msg;

   if )!Register)hInst::
       return false;
   MainWindow=Create)hInst,nCmdShow:;
   if )MainWindow==0:
       return false;

   while )GetMessage)&Msg,NULL,0,0::
      |
       TranslateMessage)&Msg:;
       DispatchMessage)&Msg:;
      "
   return Msg.wParam;
"
//---------------------------------------------------------------------------
bool Register)HINSTANCE hInst:
|
   WNDCLASS wc;

   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = )WNDPROC: WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = hInst;
   wc.hIcon         = LoadIcon)NULL, IDI_APPLICATION:;
   wc.hCursor       = LoadCursor)NULL, IDC_ARROW:;
   wc.hbrBackground = )HBRUSH: )1:;
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = szAppName;

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

"

HWND Create)HINSTANCE hInst, int nCmdShow:
|
   MaxX=GetSystemMetrics)SM_CXSCREEN:;
   MaxY=GetSystemMetrics)SM_CYSCREEN:;
   SetRectEmpty)&rect:;
   rect.left=MaxX/2;
   rect.top=MaxY/2;
   HWND hWindow = CreateWindow)szAppName, szTitle,
                               WS_POPUP | WS_VISIBLE,
                               rect.left, rect.top,
                               1, 1,
                               NULL, NULL, hInst, NULL:;
   if )hWindow != NULL:
       |
        ShowWindow)hWindow, nCmdShow:;
        UpdateWindow)hWindow:;
       "
   return hWindow;
"

void Frame3D)HDC dc, RECT *r, COLORREF TopColor, COLORREF BottomColor, int Width:
|
 POINT pl[3(;
 HPEN pTop = CreatePen)PS_SOLID,1,TopColor:;
 HPEN pBottom = CreatePen)PS_SOLID,1,BottomColor:;
 HPEN OldP = )HPEN: SelectObject)dc,pTop:;
 --r->bottom;
 --r->right;
 for )int w= Width; w--; w > 0:
    |
    pl[0(.x = r->left;
    pl[0(.y = r->bottom;
    pl[1(.x = r->left;
    pl[1(.y = r->top;
    pl[2(.x = r->right;
    pl[2(.y = r->top;
    SelectObject)dc, pTop:;
    Polyline)dc,pl,3:;
    SelectObject)dc, pBottom:;
    pl[0(.x = r->right;
    pl[0(.y = r->top;
    pl[1(.x = r->right;
    pl[1(.y = r->bottom;
    pl[2(.x = r->left-1;
    pl[2(.y = r->bottom;
    Polyline)dc,pl,3:;
    InflateRect)r, -1, -1:;
    "
 SelectObject)dc, OldP:;
 DeleteObject)pTop:;
 DeleteObject)pBottom:;
 r->bottom++;
 r->right++;
"

void OnDestroy)HWND hwnd:
|
   PostQuitMessage)0:;
"

void onPaint)HWND hwnd:
|
   PAINTSTRUCT PaintStruct;
   int Size=GetWindowTextLength)hwnd:;
   Size++;
   char *Text=new char[Size(;
   GetWindowText)hwnd,Text,Size:;
   Text[Size-1(=0;
   HDC dc = BeginPaint)hwnd,&PaintStruct:;
   SetBkMode)dc,TRANSPARENT:;


   int x; int y;
   RECT r;
   SetRectEmpty)&r:;
   DrawText)dc, Text, Size-1, &r, DT_CALCRECT:;
   x=r.right+9;
   y=r.bottom+9;
   if ))x !=rect.right: || )y !=rect.bottom::
      |
       rect.right=x;
       rect.bottom=y;
       SetWindowPos)hwnd,0,0,0,x,y,SWP_NOMOVE | SWP_NOZORDER :;
      "
   r=rect;
   r.left=0;
   r.top=0;
   Frame3D)dc, &r, RGB)255,255,255:, RGB)76,76,76:,2:;

   SetTextColor)dc,RGB)0,0,0::;
   TextOut)dc,5,5,Text,Size-1:;
   SetTextColor)dc,RGB)255,255,255::;
   TextOut)dc,4,4,Text,Size-1:;
   delete Text;
   EndPaint)hwnd, &PaintStruct:;
"

void OnMouseMove)HWND hwnd, int x, int y, UINT keyFlags:
|
    int midX=rect.right/2;
    int midY=rect.bottom/2;
    int xs=midX+)midX-x:/10;
    int ys=midY+)midY-y:/10;

    rect.left+=)xs-midX:;
    rect.top+=)ys-midY:;
    SetWindowPos)hwnd,0,rect.left,rect.top,0,0,SWP_NOSIZE | SWP_NOZORDER :;


"

LRESULT CALLBACK WndProc)HWND hWindow, UINT Message,
                         WPARAM wParam, LPARAM lParam:
|
   switch)Message:
      |
       HANDLE_MSG)hWindow, WM_DESTROY,   OnDestroy:;
       HANDLE_MSG)hWindow, WM_PAINT,     onPaint:;
       HANDLE_MSG)hWindow, WM_MOUSEMOVE, OnMouseMove:;
       default{
          return DefWindowProc)hWindow, Message, wParam, lParam:;
      "
"



//---------------------------------------------------------------------------
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Чайник
Гость
« Ответ #13 : 26-06-2004 11:14 » 

Finch, спасибо! Это уже что-то! Я попробую переделать на ассемблере
Спасибо!
Записан
Чайник
Гость
« Ответ #14 : 27-06-2004 19:19 » 

Ну, в общем, помучаться пришлось... Но не зря! Короче у меня получилось, то что я хотел. Конечно далеко не шедевр! Думаю что можно все проще сделать. Ну для меня и это пока пойдет!  Я же еще Чайник Улыбаюсь) Короче привожу свой пример (профессионалов прошу не смеяться! см. мое имя выше Улыбаюсь Правда без коментариев, ну да ничего.

;--------------------------
.386
.model flat,stdcall
option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
ClassName db "MyClass",0
AppName  db "Прикол",0
ButtonClassName db "button",0
ButtonText db "ХА-ХА-ХА",0

.data?
hInstance HINSTANCE ?
hwndButton HWND ?
CurX     dd ?
CurY     dd ?
ButtonXCenter dd ?
ButtonYCenter dd ?

.const
ButtonID equ 1
CenterX equ 35
CenterY equ 15
MaxX equ 425
MaxY equ 450

.code

start:

invoke GetModuleHandle, NULL
   mov    hInstance,eax
   invoke WinMain, hInstance,NULL,NULL,SW_SHOWDEFAULT
   invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
   LOCAL wc:WNDCLASSEX
   LOCAL msg:MSG
   LOCAL hwnd:HWND
   mov   wc.cbSize,SIZEOF WNDCLASSEX
   mov   wc.style,CS_HREDRAW or CS_VREDRAW
   mov   wc.lpfnWndProc, OFFSET WndProc
   mov   wc.cbClsExtra,NULL
   mov   wc.cbWndExtra,NULL
   push  hInst
   pop   wc.hInstance
   mov   wc.hbrBackground,COLOR_WINDOW+1
   mov   wc.lpszMenuName,NULL
   mov   wc.lpszClassName,OFFSET ClassName
   invoke LoadIcon,NULL,IDI_APPLICATION
   mov   wc.hIcon,eax
   mov   wc.hIconSm,eax
   invoke LoadCursor,NULL,IDC_ARROW
   mov   wc.hCursor,eax
   invoke RegisterClassEx, addr wc
   INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPED OR WS_CAPTION OR WS_SYSMENU OR WS_MINIMIZEBOX,CW_USEDEFAULT,\
           CW_USEDEFAULT,500,500,NULL,NULL,\
           hInst,NULL
   mov   hwnd,eax
   INVOKE ShowWindow,hwnd,SW_SHOWNORMAL
   INVOKE UpdateWindow, hwnd
   .WHILE TRUE
                INVOKE GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                INVOKE TranslateMessage, ADDR msg
                INVOKE DispatchMessage, ADDR msg
   .ENDW
   mov     eax,msg.wParam
   ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL pt:POINT

.IF uMsg==WM_DESTROY
    invoke DeleteObject,hBitmap
                 invoke PostQuitMessage,NULL
   
.ELSEIF uMsg==WM_CREATE
     invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\
                        WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                        200,400,70,30,hWnd,ButtonID,hInstance,NULL
   mov  hwndButton,eax
                mov CurX,200
                mov CurY,400

.ELSEIF uMsg==WM_PAINT
                invoke BeginPaint,hWnd,ADDR ps
                mov    hdc,eax
;......
                invoke DeleteDC,hMemDC
                invoke EndPaint,hWnd, ADDR ps
       
.ELSEIF uMsg==WM_COMMAND
   mov eax,wParam
    .IF ax==ButtonID
                     shr eax,16
            .IF ax==BN_CLICKED
                      invoke GetCursorPos,addr pt
                      invoke ScreenToClient,hWnd,addr pt
                      add pt.y,25
                      invoke ClientToScreen,hWnd,addr pt
                      invoke SetCursorPos,pt.x,pt.y
                    .ENDIF
      .ENDIF

   .ELSEIF uMsg==WM_MOUSEMOVE
                invoke GetCursorPos,addr pt
                invoke ScreenToClient,hWnd,addr pt
                mov eax,CurX
                sub eax,10
                cmp pt.x,eax
                jl finisch
                mov eax,CurY
                sub eax,10
                cmp pt.y,eax
                jl finisch
                mov eax,CurX
                add eax,80
                cmp pt.x,eax
                jg  finisch
                mov eax,CurY
                add eax,40
                cmp pt.y,eax
                jg  finisch

                mov eax,CurX
                add eax,CenterX
                mov ButtonXCenter,eax
                mov eax,CurY
                add eax,CenterY
                mov ButtonYCenter,eax

                mov eax,ButtonXCenter
                .if pt.x>eax
                    sub CurX,10
                .elseif pt.x<eax
                        add CurX,10
                .endif

                mov eax,ButtonYCenter
                .if pt.y>eax
                    sub CurY,10
                .elseif pt.y<eax
                        add CurY,10
                .endif

               .if CurX<=10
                    add CurY,10
                    add CurX,70
                .Endif
                .if CurY<=10
                    add CurY,70
                    add CurX,30
                .Endif
                mov eax,MaxX
                .If CurX>=eax
                    sub CurY,10
                    sub CurX,70
                .Endif
                mov eax,MaxY
                .if CurY>=eax
                    sub CurY,70
                    sub CurX,10
                .endif
                invoke MoveWindow,hwndButton,CurX,CurY,70,30,1
           
       .ELSE
             Invoke DefWindowProc,hWnd,uMsg,wParam,lParam
      ret
   .ENDIF
finisch:
   xor    eax,eax
   ret
WndProc endp
end start
;---------------------


В общем, извратился по полной! НО получилось! Есть правда глюк такой: когда быстро мышку двигаешь, все равно можно мышку "поймать" Улыбаюсь Видать не успевает или что? Улыбаюсь)
Может кто-нибудь поделиться своими примерчиками? Или выскажется по моему? Ошибки там, или совет какой кто даст?
Записан
Finch
Спокойный
Администратор

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


« Ответ #15 : 29-06-2004 17:19 » 

Чайник, Все полностью не смотрел, не разбирался. Но есть несколько замечаний.

Когда регистрируеш класс. И создаеш окно. Нужно обязательно проверять на правильность выполнения процедуры. Чтобы потом не получить фатальную ошибку.У меня один раз было, что окно не содавалось. В WM_CREATE есть возможность при некоторых условиях отказать в создании окна. И проверка обязательна.

WS_OVERLAPPED уже содержит Каптион, системные менюшки окна. Поэтому не нужно по новой их заводить.

В сообшении WM_MOUSEMOVE уже содержаться координаты мыши. Поэтому не нужно их повторно узнавать.

Стиль разбивания обработки всех сообшений в своих подпрограммах придумал не я. Но я его полностью поддерживаю. Когда основная программа меньше загромождена, легче работать. Старайся делать подпрограмму как можно меньше по размерам. Потом тебе будет легче работать. Я понимаю, что это учебный пример. Но все же.

Если у тебя будет еше  регистрация и создание дочерних окон. Основная программа будет загромождена до безобразия.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Чайник
Гость
« Ответ #16 : 29-06-2004 19:06 » 

Finch, спасибо тебе за конструктивную критику! Полностью с тобой согласен по всем пунктам. Буду исправляться Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines