CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Modyfikacja podczas działania Sleep'a
Strona 2 z 2

Re: Modyfikacja podczas działania Sleep'a

Nowy postNapisane: poniedziałek, 30 stycznia 2012, 00:42
przez nvdante
Rozumiem. Zawsze myślałem, że te opóźnienia związane z wykonaniem kodu są mega krótki, a tu się okazuje, że niestety jednak dość sporo trwają, bo jeśli dziesięć obrotów pętli powoduje zmianę o około sekundę to już staje się zauważalne.
A czy w takim razie możliwe jest napisane programu typu metronom, który działa na normalnym Windowsie i nie ma takich opóźnień?

Pozdrawiam

Re: Modyfikacja podczas działania Sleep'a

Nowy postNapisane: poniedziałek, 30 stycznia 2012, 11:43
przez polymorphism
Oczywiście, że jest taka możliwość. Najprościej będzie jak użyjesz timera TTimer. Metronom oparty o niego nie będzie zbyt dokładny, tzn. może pływać, ale na pewno będzie stabilniejszy niż koncepcja, którą zaprezentowałeś. Inna opcja to użyć timer multimedialny -> link. Jeszcze inna opcja, chyba najdokładniejsza, to użycie strumieni MIDI lub audio.

Re: Modyfikacja podczas działania Sleep'a

Nowy postNapisane: wtorek, 31 stycznia 2012, 01:01
przez nvdante
OK, dziękuję za informację. Link już przeczytałem. Póki co nie wygląda skomplikowanie, więc być może uda mi się to wykorzystać.

Pozdrawiam

Re: Modyfikacja podczas działania Sleep'a

Nowy postNapisane: wtorek, 31 stycznia 2012, 06:00
przez Cyfrowy Baron
Jeżeli szukasz multimedialnego timera, to mam tutaj taki kod:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
typedef struct tagANIMATEINFO
{
    HWND HForm;
    Graphics::TBitmap *Bitmap;
} ANIMATEINFO, *LPANIMATEINFO;

void CALLBACK TimerProc(unsigned int uID, unsigned int uMsg,
                              DWORD dwUser, DWORD dw1, DWORD dw2);

class TForm1 : public TForm
{
__published: // IDE-managed Components
    TButton *Button1;
    TImage *Image1;

    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

private: // User declarations
    int TimerID;
    LPANIMATEINFO lpani;

public: // User declarations
    __fastcall TForm1(TComponent* Owner);
    int __fastcall GetResolution(target);
    int __fastcall StartMMTimer(int Interval, int Resolution, DWORD data);
    void __fastcall KillMMTimer(int TimerID);
};


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
#include <mmsystem.h>

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TimerID = 0;
}

int __fastcall TForm1::GetResolution(int target)
{
    TIMECAPS tc;
    unsigned int uiTimerRes;

    timeGetDevCaps(&tc, sizeof(TIMECAPS));
    uiTimerRes = min(max((int)tc.wPeriodMin, target), (int)tc.wPeriodMax);
    timeBeginPeriod(uiTimerRes);
    return uiTimerRes;
}

int __fastcall TForm1::StartMMTimer(int Interval,
                                       int Resolution, DWORD data)
{
    return timeSetEvent(Interval, Resolution, TimerProc,
    data, TIME_PERIODIC);
}

void __fastcall TForm1::KillMMTimer(int FTimerID)
{
    timeKillEvent(FTimerID);
}

void CALLBACK TimerProc(unsigned int uID, unsigned int uMsg,
DWORD dwUser,
    DWORD dw1, DWORD dw2)
{
    LPANIMATEINFO lpani = (ANIMATEINFO *)dwUser;

    HDC Hdc = GetDC(lpani->HForm);

    static int pos = 0;
    pos = pos + 5;
    if (pos > 300) pos = 0;

    RECT R = Rect(pos - 5, 0, pos, lpani->Bitmap->Height);
    FillRect(Hdc, &R, GetStockObject(LTGRAY_BRUSH));

    ::BitBlt(Hdc, pos, 0, lpani->Bitmap->Width, lpani->Bitmap->Height,
             lpani->Bitmap->Canvas->Handle, 0, 0, SRCCOPY);

    ReleaseDC(lpani->HForm, Hdc);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    lpani = new ANIMATEINFO;
    lpani->HForm = Handle;
    lpani->Bitmap = Image1->Picture->Bitmap;

    int Resolution = GetResolution(1);
    TimerID = StartMMTimer(10, Resolution, (DWORD)lpani);
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    delete lpani;
    if (TimerID) KillMMTimer(TimerID);
}


Przedstawiony kod przeprowadza animację w Image1 w oparciu o multimedialny timer.