logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak przesuwać elementy w schemacie programu? Reverse engineering

antyBrygadaW 15 Maj 2005 19:40 2280 15
REKLAMA
  • #1 1495430
    antyBrygadaW
    Poziom 15  
    Posty: 190
    Pomógł: 1
    Ocena: 9
    chciałem Was zapytać jak można zrobić to co zrobił jeden z forumowiczów w swoim programie - który przedstawił tutaj https://www.elektroda.pl/rtvforum/topic290128.html

    konkretnie chodzi o to jak obsługiwane jest pole robocze programu, zwłaszcza to w jaki sposób przesuwane są poszczególne elementy w schemacie...
  • REKLAMA
  • #2 1495549
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    zapytaj autora tematu którego link podałeś w swoim poście.. on sam będzie wiedział najlepiej jak to zrobił.. (logika)

    reverse engineering - niepolecam gdyż to jest operacja czasochłonna i nie zawsze daje spodziewane efekty - otrzymany kod asemblera mimo iż łatwo da sie podzielić na funkcje, to brak nazw z kodu źródłowego zmniejsza czytelność takiego kodu, a brak komentaży powyższą wade pogłębia.. mi samemu raz udał się reverse engin' dla kodu który liczył niecałe 490B.. cała operacja zajeła mi około 2 godzin..
  • REKLAMA
  • #3 1496960
    kloszi
    Poziom 21  
    Posty: 547
    Pomógł: 34
    Ocena: 88
    Własnie cały czas pracuję nad tym symulatorem i mam nadzieje go skończyć do końca maja 2005. Na wszelkie pytania gg: 1791969. A tak na marginesie : Co to jest "reverse engineering"??
    Zapraszam na http://ciapek.uci.agh.edu.pl/~mkolodzi/
  • REKLAMA
  • #5 1507184
    antyBrygadaW
    Poziom 15  
    Posty: 190
    Pomógł: 1
    Ocena: 9
    no nie no, wszycy mnie olewają... nikt mi nie chce powiedzieć... dlaczego, dlaczego ;)? przecież nie mam zamiaru tworzyć konkurencji tylko chciałbym wiedzieć jak to można by było zrobić!

    jedyny pomysł jaki mi przychodzi do głowy to ponowne rysowanie całości po każdym poruszeniu elementu... ale to napewno nie jest tak zrobione, bo to by było nie dość, że wolne to jeszcze trudne... więc moglibyście mi powiedzieć jak zrobione jest w tym i podobnych programach przesuwanie elementów na schemacie....
  • #6 1507701
    kloszi
    Poziom 21  
    Posty: 547
    Pomógł: 34
    Ocena: 88
    Można przez XOR-owanie(Form1->Canvas->Pen->Mode=pmXor ) tego co się znajduje na obrazie jest to sposób dość szybki ale niestety.... w czcionkach nie da ustawić sie tej opcji . Dlatego jest wybrana inna opcja przerysowywanie wszystkiego na "żywca" i całkowicie nieźle to działa jak widać. Jak będe miał czas to zrobie to wszystko przez xorowanie (trzeba napisać klasę z fontami która bedzie miała taka opcję). Tymczasem nie mam czasu ponieważ pracuję na pełny etat i jeszcze pisze dokumentacje do programu no i musze wykończyć ładnie projekt. Myśle jeszcze go na ang przetłumaczyć i jak nie znajde lepiej płatnej pracy to uciekam z kraju.

    Tymczasem zapraszam na moją stronke www.kloszi.prv.pl (zawsze tam będzie się znajdował jakiś link do najnowszej wersji symulatora)
  • #7 1509022
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    Można to szybko i łatwo zrobić, ale będzie wymagało trochę pamięci.
    Trzeba najpierw do jakiejś osobnej bitmapy narysować całość, ale bez przesuwanego obiektu.
    A przesuwanie polega na tym, że do okna wklejamy bitmapę a następnie przesuwany obiekt w odpowiedniej pozycji, takie wklejanie powtarzamy przy każdym ruchu myszki. Szybkie to cholernie jest i prędkość rysowania nie jest zależna od stopnia komplikacji grafiki. :)
  • REKLAMA
  • #8 1509096
    kloszi
    Poziom 21  
    Posty: 547
    Pomógł: 34
    Ocena: 88
    oj czy takie szybkie tobym się zastanawiał.....Po pierwsz próbowałem stworzyć pare warstw(np. warstwa przesuwana i warstwa schematu). Liczymy wielkośc pamieci 1024*800*3 (ta trójka poniewaz po bajcie dajemy na RGB) =2 457 600 czyli ok 2,5MB trzeba dodawać za każdyma razem no a licząc żeby animacja przesuwania była płynna to trzeba 10 razy/sec dodać takie macierze. Najlepiej jednak jest korzystac z WinApi.powyzszy sposób próbowałem zaimplementować w c++ z miernym skutkiem
  • #9 1510070
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    Zauwazylem temat i postanowilem napisac program obslugujacy drag&drop.
    Aplikacja napisana na VC.

    Screen znajdziecie tutaj: http://img239.echo.cx/img239/4543/elsym8dh.jpg

    Osoby zainteresowane kodem zrodlowym lub plikiem wykonywalnym zapraszam na priv.
    Załączniki:
    • ElSimulator.zip (194.53 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #10 1511877
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    kloszi napisał:
    oj czy takie szybkie tobym się zastanawiał.....

    No szybkie to będzie, tylko kwestia jak zostanie wykonane ;)

    Jeżeli zarówno "tło", jak i przesuwany obiekt będą umieszcone w pamięci karty graficznej, to będzie rakieta ;), tylko implementacja tego była by conieco skomplikowana.

    Nie wiem, jakie funkcje w zakresie operacji na bitmapach oferuje winzgroza, ale na amidze takie rzeczy bez problemy robiłem, konkretniej to renderowałem do dwóch osobnych bitmap i sklejałem je razem, a potem jeszcze wklejałem to wszystko do okna.

    A zresztą wcale nie trzeba wklejać całego tła, a potem przesuwanego obiektu, wystarczy wkleić tło w miejscu, które akurat zostało przez obiekt odsłonięte, a obiektem przesunąć. winda musi mieć do tego jakieś funkcje (znaczy do przenoszenia fragmentu bitmapy i wklejania), a jak nie to to
    "windoze sux" po stokroć ;)

    No ale faktytcznie przy takich prostych grafikach wektorowych, jak schemat nie ma co się bawić w osobne bitmapy, gorzej było by np. z rysunkiem architektonicznym, chociaż i tu można stosować sztuczki typu LOD (Level Of Details)
  • #11 1511920
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Większość współczesnych kart grafiki obsługuje DirectX, więc można przesunąć środek ciężkości w stronę tych bibliotek, lub podobnych - SDL, OpenGL(Mesa)...
  • #12 1512643
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    Na prosbe bygady...zalanczam fragmety zrodel programu

    Definicje oraz uzyte struktury danych:
    // DET - draw element type
    #define DET_LOGIC_NOT							1
    #define DET_LOGIC_AND							2
    #define DET_LOGIC_OR							3
    
    // 
    typedef struct
    {
    	UINT uiType;
    	CBitmap* pkObjectBmp;
    
    } ELEMENT_INFO;
    
    typedef struct
    {
    	ELEMENT_INFO* pkInfo;
    	CRect rcElement;
    
    } DRAW_ELEMENT_INFO;
    
    typedef CTypedPtrList< CPtrList, ELEMENT_INFO* > ELEMENT_INFO_LIST;
    typedef CTypedPtrList< CPtrList, DRAW_ELEMENT_INFO* > DRAW_ELEMENT_INFO_LIST;


    Sposob wczytania danych w programie:

    // Load all bitmaps
    loadElement( DET_LOGIC_NOT, IDB_LOGIC_NOT_BITMAP );
    loadElement( DET_LOGIC_OR, IDB_LOGIC_OR_BITMAP );
    loadElement( DET_LOGIC_AND, IDB_LOGIC_AND_BITMAP );


    funkcja wczytjaca:

    void CMainFrame::loadElement( const UINT cuiType, const UINT cuiResID )
    {
    	// Create
    	ELEMENT_INFO* pkNewInfo = new ELEMENT_INFO;
    
    	// Set
    	pkNewInfo->uiType = cuiType;
    	pkNewInfo->pkObjectBmp = new CBitmap();
    	pkNewInfo->pkObjectBmp->LoadBitmap( cuiResID );
    
    	BITMAP kBitmap;
    	pkNewInfo->pkObjectBmp->GetBitmap( &kBitmap );
    	pkNewInfo->pkObjectBmp->SetBitmapDimension( kBitmap.bmWidth, kBitmap.bmHeight );
    
    	// Add
    	m_kElementsList.AddHead( pkNewInfo );
    }


    Rysowanie:

    void CElSimulatorView::OnDraw(CDC* pDC)
    {
    	CElSimulatorDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    
    
    	CDC MemDC;
    	MemDC.CreateCompatibleDC( pDC );
    
    	// get vec
    	DRAW_ELEMENT_INFO_LIST* pkaDElements = pDoc->getDrawElementsListPtr();
    
    	POSITION pos = pkaDElements->GetHeadPosition();
    	DRAW_ELEMENT_INFO* pkDInfo;
    	while ( pos && ( pkDInfo = pkaDElements->GetNext( pos ) ) != NULL )
    	{
    		// draw
    		CBitmap* pkOldBitmap = ( CBitmap* )MemDC.SelectObject( ( CBitmap* )pkDInfo->pkInfo->pkObjectBmp );
    
    		CSize size = pkDInfo->pkInfo->pkObjectBmp->GetBitmapDimension();
    		pDC->BitBlt( pkDInfo->rcElement.left, pkDInfo->rcElement.top, size.cx, size.cy, &MemDC, 0, 0, SRCCOPY );
    
    		if ( pkDInfo == m_pkSelectedItem )
    			pDC->DrawFocusRect( pkDInfo->rcElement );
    	}
    }


    Kod odpowiedzialny za wybieranie i drag&drop

    void CElSimulatorView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	CElSimulatorDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    
    	//
    	CPoint ptTmp = point;
    	ptTmp.x += GetScrollPos( SB_HORZ );
    	ptTmp.y += GetScrollPos( SB_VERT );
    
    	// get vec
    	DRAW_ELEMENT_INFO_LIST* pkaDElements = pDoc->getDrawElementsListPtr();
    
    	// Check which element was clicked
    	bool bFound = false;
    	POSITION pos = pkaDElements->GetHeadPosition();
    	DRAW_ELEMENT_INFO* pkDInfo;
    	while ( pos && ( pkDInfo = pkaDElements->GetNext( pos ) ) != NULL )
    	{
    		// Got it
    		if ( pkDInfo->rcElement.PtInRect( ptTmp ) )
    		{
    			bFound = true;
    			m_pkSelectedItem = pkDInfo;
    			m_pkDragingItem = pkDInfo;
    
    			m_ptAdd.x = ptTmp.x - pkDInfo->rcElement.left;
    			m_ptAdd.y = ptTmp.y - pkDInfo->rcElement.top;
    
    			Invalidate();
    			break;
    		}
    	}
    
    	// No item clicked - clear selection
    	if ( !bFound )
    		m_pkSelectedItem = NULL;
    
    	// Call base
    	CScrollView::OnLButtonDown(nFlags, point);
    }
    
    void CElSimulatorView::OnLButtonUp(UINT nFlags, CPoint point)
    {
    	// Clear
    	m_pkDragingItem = NULL;
    	Invalidate();
    
    	CScrollView::OnLButtonUp(nFlags, point);
    }
    
    void CElSimulatorView::OnMouseMove(UINT nFlags, CPoint point)
    {
    	// Drag item
    	if ( m_pkDragingItem != NULL )
    	{
    		// get size
    		CSize size = m_pkDragingItem->rcElement.Size();
    
    		//
    		CPoint ptTmp = point;
    		ptTmp.x += GetScrollPos( SB_HORZ );
    		ptTmp.y += GetScrollPos( SB_VERT );
    
    		ptTmp -= m_ptAdd;
    
    		// set new pos
    		m_pkDragingItem->rcElement = CRect( ptTmp, size );
    
    		Invalidate();
    	}
    
    	CScrollView::OnMouseMove(nFlags, point);
    }


    Wykonanie calej aplikacji symylujacej jest proste ale wymaga duzego nakladu czasu i pracy.

    Jak widac wcale nie potrzeba duzej ilosci pamieci za zapamietywanie elementow, wystarczy dobry pomysl.

    Narazie prenoszenie obsluguje tylko jeden element ale nic nie stoi na przeszkodzie aby zbudowac cos w rodzaju polaczonych grup. Gdzie poruszenie jednego elementu spowoduje przemieszczenie innego.

    Lub cos bardziej zaawansowanego.
  • #13 1514123
    antyBrygadaW
    Poziom 15  
    Posty: 190
    Pomógł: 1
    Ocena: 9
    wielkie dzięki, to co wkleiłeś jest podobne do tego co dostałem od kolegi wyżej, ale niestety także nie wyjaśnia sprawy...

    nie wiem czy ja dobrze odczytałem, ale Twój programik unieważnia jakiś region... i co dalej? rysuje od nowa? a gdyby były jeszcze połączenia jak u kolegi wyżej, to dość ciężko byłoby to rysować od nowa, trzebaby zapamiętywać trasę połączeń...

    jak już pisałem, nie chodzi mi o skopiowanie tego programu, chciałem się dowiedzieć jedynie jak obsługiwane jest przemieszczanie elementów na schemacie... poza tym podkreślam, że jestem początkującym programistą windows, ;)...

    przy okazji, ktoś może wyjaśnić co znaczy taki zapis:
    pkNewInfo->pkObjectBmp->SetBitmapDimension( kBitmap.bmWidth, kBitmap.bmHeight );
  • #14 1515143
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    antyBrygadaW napisał:
    przy okazji, ktoś może wyjaśnić co znaczy taki zapis:
    pkNewInfo->pkObjectBmp->SetBitmapDimension( kBitmap.bmWidth, kBitmap.bmHeight );


    Struktura przechowuje informacje, dokladnie adres obiektu CBitmap (pkObjectBmp). W podanym fragmecie wywolywane jest funkcja ustawiajaca rozmiar bitmapy, aby mozna bylo pozniej z tego korzystac.

    A jesli chodzi o odrysowywanie polaczen to sprawa jest prosta. Kazdy wire mozna podzielic na sektory, kazdy sektor moze miec rysowany inny koniec i poczatek (np rysowanie koleczek na polaczeniach), posiada swoja pozycja, info o grubosci lini, itp.

    Pojedynczy wire moze reprezentowac tablica, lista, itp takich wlasnie sektorow. Czyli taki wire moze miec bardzo rozne ksztalty.

    Jesli przenoszony obiekt mial by informacje ze cos jest z nim polaczone (jest z nim w grupuie) powinien razem ze swoim ruchem wywolac funkcje przesowajaca zgrupowane elementy.

    Aby poprawic rysowanie mozna oczywiscie uzyc podwojnego buforowania + InvalidateRect.
  • #15 1517675
    kloszi
    Poziom 21  
    Posty: 547
    Pomógł: 34
    Ocena: 88
    No tak wszystko ładnie ale elementy się przysłaniają a nie są przeźroczyste. Po drugie po co sie bawić obrazkami jak można narywować wszystko sobie z podstawowych elementów kresek kropek itp:).Po drugie jesli komponentów było by więcej i były by znacznych rozmiarów to mogło by całkowicie "zapchać" karte graficzną. Przy bardzo wielkich projektach rysowanie wszystko z podstawowych elementów spowolniło by rysowanie ale to nie jest oprogramowanie do pisania wielkich projektów tylko do początkowej nauki pisania programów na procesor 89C51.
    zapraszam na www.kloszi.prv.pl
  • #16 1517822
    antyBrygadaW
    Poziom 15  
    Posty: 190
    Pomógł: 1
    Ocena: 9
    o tu koledzy trafili w sedna sprawy,
    podwójne buforowanie - jak to się robi?

Podsumowanie tematu

✨ Dyskusja dotyczy metod przesuwania elementów w schemacie programu, zwłaszcza w kontekście reverse engineeringu i optymalizacji rysowania. Reverse engineering kodu asemblerowego jest czasochłonny i utrudniony przez brak nazw i komentarzy. Proponowane techniki przesuwania elementów obejmują: ponowne rysowanie całego schematu po każdym ruchu (co jest wolne i nieefektywne), użycie trybu rysowania XOR (pmXor) do szybkiego "kasowania" i rysowania elementów, a także rysowanie na osobnej bitmapie tła bez przesuwanego obiektu i wklejanie jej wraz z przesuwanym elementem przy każdym ruchu myszy, co zapewnia wysoką wydajność kosztem większego zużycia pamięci. Dyskutowano także o problemach z pamięcią przy wielowarstwowym buforowaniu i o możliwości wykorzystania funkcji WinAPI do operacji na bitmapach. Wspomniano o zastosowaniu podwójnego buforowania i funkcji InvalidateRect dla poprawy jakości rysowania. Wskazano, że przesuwanie elementów połączonych wymaga zarządzania grupami i aktualizacji połączeń, które mogą być reprezentowane jako listy sektorów z własnymi właściwościami graficznymi. Zasugerowano także wykorzystanie bibliotek graficznych takich jak DirectX, SDL czy OpenGL dla lepszej wydajności. Przykładowy fragment kodu w C++ pokazuje strukturę danych przechowującą elementy schematu i sposób ładowania bitmap elementów. Poruszono też temat rysowania elementów z podstawowych kształtów zamiast bitmap, co może być korzystne przy prostych projektach edukacyjnych. Na koniec pojawiło się pytanie o implementację podwójnego buforowania w Windows.
Wygenerowane przez model językowy.
REKLAMA