Informacja dla mnie że coś się zmieniło w zmiennej

0

Yagga yo!

Mam taki problem. Chce wiedzieć, kiedy zmieni się jakiś string. Konkretnie jest to Titlebar pewnego procesu.
Czy mam zrobić powiedzmy jakiś timer, ktory co ileś tam milisekund sprawdza, czy tekst jest taki sam jak iles milisek. wcześniej?
Bo nie ma tam blisko Process.MainWindowTitle żadnego eventu który by mnie informował.

Z góry dzięki!
Waiting for reply :)

2

Informacji, że się coś zmieniło nie dostaniesz, bo MainWindowTitle to właściwość. Jej "zawartość" znana jest wtedy, gdy dopiero o nią "poprosisz" - wywołasz getter. I ten getter w tym przypadku wywołuje GetWindowText. W teorii da się się zrobić to za pomocą timera i pobierać tekst z okna ileśtam razy na sekundę. W praktyce, IMO lepiej polegać na zdarzeniach. Żeby zrobić to tą metodą musisz (nie mam głowy w tej chwili, żeby to przetłumaczyć) zsubclassować okno i wyłapać wiadomość typu WM_SETTEXT. Problem jest taki, że zrobienie tego w osobnym procesie nie jest takie proste - trzeba uruchomić zdalny wątek, zsubclassować okno, podać nową procedurę okna, no i nie mówiąc o tym, że C# średnio się do tego nadaje i lepiej zrobić to w C++. Ewentualnie użyć globalnego hooka na wiadomości - ale to również w C++.

Tak, zrób to za pomocą timera.

0

Dobra zrobiłem coś takiego, co prawda na razie nie dla zmiany nazwy okna tylko na rzecz testu, podwójnego kliknięcia.

private void Form1_Load(object sender, EventArgs e)
        {
            IntPtr hnd = Process.GetProcessesByName("notepad")[0].MainWindowHandle;

            SubclassHWND sub = new SubclassHWND();
            sub.AssignHandle(hnd);
        }
    }
    public class SubclassHWND : NativeWindow
    {
        private const int WM_LBUTTONDBLCLK = 0x0203;

        protected override void WndProc(ref Message m)
        {
            System.Diagnostics.Debug.WriteLine(m.ToString());

            switch (m.Msg)
            {
                case WM_LBUTTONDBLCLK:
                    {
                        MessageBox.Show("Aaa!");
                        break;
                    }
            }
            base.WndProc(ref m);
        }
    }

Tylko oczywiście nie działa. Co robię źle?
Notatnik jest oczywiście podczas testu uruchomiony w tylko jednej instancji.

1

Jakbyś przeczytał dokumentację, to byś wiedział, że nie zadziała to dla innego procesu. Pod spodem, AssignHandle odpala SetWindowLong, które zwróci ci NULL. Musisz SetWindowLong uruchomić w procesie, którego okno chcesz zsubclassować (za pomocą CreateRemoteThread, ale jest to generalnie bardziej skomplikowane, zwłaszcza w C#).

0

Dzięki za pomoc tak czy siak. Znalazłem taki kod co prawda http://blogs.msdn.com/b/jmstall/archive/2006/09/28/sample-create-remote-thread.aspx
Ale póki co troche mnie to przeraża.
Tak się zastanawiam, dlaczego Microsoft nie udostępnił w .NET narzędzi do różnych rzeczy związanych z WinAPI i trzeba się bawić importując funkcje? Czy to znaczy że C++ jest wiecznie żywy, a C# to naprawdę zabawka?

2

Tak, C# to zabawka, bo nie ma gotowej klasy we Frameworku do wstrzykiwania kodu (co do procesu nie-dotnetowego i tak pewnie się nie uda, bo nie wczyta się CLR).

0
ubuntuser napisał(a)

Tak się zastanawiam, dlaczego Microsoft nie udostępnił w .NET narzędzi do różnych rzeczy związanych z WinAPI i trzeba się bawić importując funkcje?

.NET to w znacznej części nakładka na WinAPI...

Czy to znaczy że C++ jest wiecznie żywy, a C# to naprawdę zabawka?

Tak, oczywiście. Każdy język, który nie ma wbudowanego każdego kawałka kodu, który jest akurat Tobie potrzebny, to zabawka.

2

Tak, C# to zabawka, ponieważ nie ma w bibliotece standardowej wrapperów do wszystkich istniejących API, w przeciwieństwie oczywiście do C++ który w bibliotece standardowej nie ma nawet obsługi wątków, nie wspominając o takim kosmosie jak sprawdzanie czy plik istnieje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1