Blog (22)
Komentarze (619)
Recenzje (0)
@alucosoftwareTata programista...

Tata programista...

Praca na własny rachunek niesie ze sobą wiele korzyści. Jedną z nich jest możliwość częstszego przebywania bliżej rodziny (o ile takową posiadamy). Praca na własny rachunek w charakterze programisty nakłada obowiązek posiadania co najmniej jednego komputera, który współdzielimy (bądź nie) z pozostałymi domownikami. Jeżeli tymi domownikami są małe dzieci - oj, strzeżcie się pliki i foldery, albowiem wasze dni zostały policzone.

Sam mam dwójkę pociech, synka i córeczkę. Och, ach :) Synek, z racji swojego wieku (2,5 roku) i zawodu taty, szybko rozwinął grupę zdolności psychofizycznych umożliwiających sprawne poruszanie się po zakamarkach Internetu. Jeśli przez przypadek pozostawię myszkę "luzem", już po paru chwilach ze zdumieniem obserwuję "kota kota Fimejona" skaczącego po ekranie i Bonifacego wylegującego się na babcinym zapiecku... Pięć kliknięć myszką i YouTube gra pełną parą :) Niech mu będzie.

Swego czasu, na potrzeby świetego spokoju, wskazałem synkowi ikonę do TuxPainta. Wywołało to w nim falę niespotykanej dotąd radości, tym bardziej, że poza samym malowaniem, program oferuje możliwość umieszczania na obrazkach tekstu. Klawiaturę opanował błyskawicznie. Tym większe było moje zdziwienie, kiedy synek, z "chronionego", pełnoekranowego trybu "Dla dzieci", powracał do Pulpitu - bo mu się malowanie znudziło - i rozpoczynał fragmentację moich programistycznych projektów. Ech...

Tylko dla wybranych (klawiszy...)

419649

Ostatnio natrafiłem na stronę www.virtualpiano.net i zaprezentowałem znalezisko małemu psotnikowi. Zabawa niesłychana! Z tym, że gra na wirtualnym pianinie odbywa się za pomocą wybranych - a nie WSZYSTKICH klawiszy :P. Hmm, ale przecież tata zajmuje się tym czym zajmuje. Wziąłem więc synka na kolana i razem zabraliśmy się za pisanie "oprogramowania pomocniczego". Porady malucha były na tyle owocne, że już po kilkunastu minutach klawiatura została okiełznana, a program ukończony (kliknij tutaj, aby pobrać program).

419651

Aplikacja wymaga .NET Framework 2.0 (Systemy Windows Vista i wyżej posiadają środowisko uruchomieniowe .NET w odpowiedniej wersji). Program blokuje przetwarzanie przez system operacyjny tych klawiszy, które nie znajdują się na "białej liście" (w uproszczeniu, ponieważ nie jest to do końca prawda). Jeśli do tego ukryjemy myszkę w sejfie, to możemy pozwolić naszym dzieciom na odrobinę zabawy z wykorzystaniem sprzętu komputerowego, bez konieczności nieustannego zerkania przez ramię.

Efekt końcowy jak na załączonym obrazku :)

419654

Uwaga! Dzieci nie powinny spędzać przy komputerze dłużej niż 20 minut dziennie.

* w ofercie posiadam także inne programistyczne wynalazki dla rodziców małych pociech ;)

Poniżej załączam kod źródłowy (w wersji "wyścig z czasem"). Klasa InterceptKeys to zmodyfikowana implementacja mechanizmu haków w .NET Stephena Toub'a (http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx ).


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace PreventKeys
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormKeys());
        }
    }

    public class FormKeys : Form
    {
        Button buttonPreventKeys;

        public FormKeys()
        {
            this.Text = "Klawiatura dla psotnika";
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Size = new System.Drawing.Size(480, 150);

            RichTextBox allowableKeysRichTextBox = new RichTextBox();
            allowableKeysRichTextBox.BorderStyle = BorderStyle.None;
            allowableKeysRichTextBox.BackColor = System.Drawing.Color.White;
            allowableKeysRichTextBox.ReadOnly = true;
            allowableKeysRichTextBox.Dock = DockStyle.Fill;

            InterceptKeys.AllowableKeysRichTextBox = allowableKeysRichTextBox;

            allowableKeysRichTextBox.GotFocus += new EventHandler(allowableKeysRichTextBox_GotFocus);
            allowableKeysRichTextBox.LostFocus += new EventHandler(allowableKeysRichTextBox_LostFocus);

            buttonPreventKeys = new Button();
            buttonPreventKeys.Text = "Zablokuj pozostałe klawisze";
            buttonPreventKeys.Dock = DockStyle.Bottom;
            buttonPreventKeys.Click += new EventHandler(buttonPreventKeys_Click);

            Label label = new Label();
            label.Text = "Kliknij myszką na poniższym polu i naciśnij klawisze, które mają być dostępne dla dziecka";
            label.AutoSize = true;
            label.Padding = new System.Windows.Forms.Padding(4);
            label.Dock = DockStyle.Top;

            this.Controls.Add(allowableKeysRichTextBox);
            this.Controls.Add(label);
            this.Controls.Add(buttonPreventKeys);

            Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
        }

        void allowableKeysRichTextBox_LostFocus(object sender, EventArgs e)
        {
            InterceptKeys.UnHook();
            InterceptKeys.HookMode = InterceptKeys.Mode.PreventOtherKeys;
        }

        void allowableKeysRichTextBox_GotFocus(object sender, EventArgs e)
        {
            buttonPreventKeys.Text = "Zablokuj pozostałe klawisze";
            buttonPreventKeys.Tag = null;
            InterceptKeys.UnHook();

            InterceptKeys.HookMode = InterceptKeys.Mode.PrepareAllowableKeys;
            InterceptKeys.Hook();
        }

        void buttonPreventKeys_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;

            if (button.Tag == null)
            { 
                InterceptKeys.Hook();
                button.Text = "Odblokuj wszystkie klawisze";
                button.Tag = true;
            }
            else
            {
                InterceptKeys.UnHook();
                button.Text = "Zablokuj pozostałe klawisze";
                button.Tag = null;
            }
        }

        void Application_ApplicationExit(object sender, EventArgs e)
        {
            InterceptKeys.UnHook();
        }
    }

    public static class InterceptKeys
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        public enum Mode
        {
            PrepareAllowableKeys,
            PreventOtherKeys
        }

        public static Mode HookMode { get; set; }
        public static RichTextBox AllowableKeysRichTextBox { get; set; }

        public static void Hook()
        {
            _hookID = SetHook(_proc);
        }

        public static void UnHook()
        {
            UnhookWindowsHookEx(_hookID);
        }

        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);

                string keyName = Enum.GetName(typeof(Keys), vkCode);
                bool found = false;

                // Uuuu, ale nieefektywny sposób :)
                // A ile pamięci marnujemy... Dobrze, że GC działa jak należy...
                // Nie ma czasu na zabawę w wyrażenia regularne...
                string[] split = AllowableKeysRichTextBox.Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                for (int j = 0; j < split.Length; ++j)
                {
                    if (split[j] == keyName)
                    {
                        found = true;
                        break;
                    }
                }

                if (HookMode == Mode.PrepareAllowableKeys)
                {
                    if (!found)
                        AllowableKeysRichTextBox.Text += String.Format("{0} ", keyName);
                    else
                        return new IntPtr(1);
                }
                else
                {
                    if (found)
                        return CallNextHookEx(_hookID, nCode, wParam, lParam);
                    else
                        return new IntPtr(1);
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }
}
Wybrane dla Ciebie
Komentarze (30)

Cenimy Twoją prywatność

Kliknij "AKCEPTUJĘ I PRZECHODZĘ DO SERWISU", aby wyrazić zgodę na korzystanie w Internecie z technologii automatycznego gromadzenia i wykorzystywania danych oraz na przetwarzanie Twoich danych osobowych przez Wirtualną Polskę, Zaufanych Partnerów IAB (870 partnerów) oraz pozostałych Zaufanych Partnerów (403 partnerów) a także udostępnienie przez nas ww. Zaufanym Partnerom przypisanych Ci identyfikatorów w celach marketingowych (w tym do zautomatyzowanego dopasowania reklam do Twoich zainteresowań i mierzenia ich skuteczności) i pozostałych, które wskazujemy poniżej. Możesz również podjąć decyzję w sprawie udzielenia zgody w ramach ustawień zaawansowanych.


Na podstawie udzielonej przez Ciebie zgody Wirtualna Polska, Zaufani Partnerzy IAB oraz pozostali Zaufani Partnerzy będą przetwarzać Twoje dane osobowe zbierane w Internecie (m.in. na serwisach partnerów e-commerce), w tym za pośrednictwem formularzy, takie jak: adresy IP, identyfikatory Twoich urządzeń i identyfikatory plików cookies oraz inne przypisane Ci identyfikatory i informacje o Twojej aktywności w Internecie. Dane te będą przetwarzane w celu: przechowywania informacji na urządzeniu lub dostępu do nich, wykorzystywania ograniczonych danych do wyboru reklam, tworzenia profili związanych z personalizacją reklam, wykorzystania profili do wyboru spersonalizowanych reklam, tworzenia profili z myślą o personalizacji treści, wykorzystywania profili w doborze spersonalizowanych treści, pomiaru wydajności reklam, pomiaru wydajności treści, poznawaniu odbiorców dzięki statystyce lub kombinacji danych z różnych źródeł, opracowywania i ulepszania usług, wykorzystywania ograniczonych danych do wyboru treści.


W ramach funkcji i funkcji specjalnych Wirtualna Polska może podejmować następujące działania:

  1. Dopasowanie i łączenie danych z innych źródeł
  2. Łączenie różnych urządzeń
  3. Identyfikacja urządzeń na podstawie informacji przesyłanych automatycznie
  4. Aktywne skanowanie charakterystyki urządzenia do celów identyfikacji

Cele przetwarzania Twoich danych przez Zaufanych Partnerów IAB oraz pozostałych Zaufanych Partnerów są następujące:

  1. Przechowywanie informacji na urządzeniu lub dostęp do nich
  2. Wykorzystywanie ograniczonych danych do wyboru reklam
  3. Tworzenie profili w celu spersonalizowanych reklam
  4. Wykorzystanie profili do wyboru spersonalizowanych reklam
  5. Tworzenie profili w celu personalizacji treści
  6. Wykorzystywanie profili w celu doboru spersonalizowanych treści
  7. Pomiar efektywności reklam
  8. Pomiar efektywności treści
  9. Rozumienie odbiorców dzięki statystyce lub kombinacji danych z różnych źródeł
  10. Rozwój i ulepszanie usług
  11. Wykorzystywanie ograniczonych danych do wyboru treści
  12. Zapewnienie bezpieczeństwa, zapobieganie oszustwom i naprawianie błędów
  13. Dostarczanie i prezentowanie reklam i treści
  14. Zapisanie decyzji dotyczących prywatności oraz informowanie o nich

W ramach funkcji i funkcji specjalnych nasi Zaufani Partnerzy IAB oraz pozostali Zaufani Partnerzy mogą podejmować następujące działania:

  1. Dopasowanie i łączenie danych z innych źródeł
  2. Łączenie różnych urządzeń
  3. Identyfikacja urządzeń na podstawie informacji przesyłanych automatycznie
  4. Aktywne skanowanie charakterystyki urządzenia do celów identyfikacji

Dla podjęcia powyższych działań nasi Zaufani Partnerzy IAB oraz pozostali Zaufani Partnerzy również potrzebują Twojej zgody, którą możesz udzielić poprzez kliknięcie w przycisk "AKCEPTUJĘ I PRZECHODZĘ DO SERWISU" lub podjąć decyzję w sprawie udzielenia zgody w ramach ustawień zaawansowanych.


Cele przetwarzania Twoich danych bez konieczności uzyskania Twojej zgody w oparciu o uzasadniony interes Wirtualnej Polski, Zaufanych Partnerów IAB oraz możliwość sprzeciwienia się takiemu przetwarzaniu znajdziesz w ustawieniach zaawansowanych.


Cele, cele specjalne, funkcje i funkcje specjalne przetwarzania szczegółowo opisujemy w ustawieniach zaawansowanych.


Serwisy partnerów e-commerce, z których możemy przetwarzać Twoje dane osobowe na podstawie udzielonej przez Ciebie zgody znajdziesz tutaj.


Zgoda jest dobrowolna i możesz ją w dowolnym momencie wycofać wywołując ponownie okno z ustawieniami poprzez kliknięcie w link "Ustawienia prywatności" znajdujący się w stopce każdego serwisu.


Pamiętaj, że udzielając zgody Twoje dane będą mogły być przekazywane do naszych Zaufanych Partnerów z państw trzecich tj. z państw spoza Europejskiego Obszaru Gospodarczego.


Masz prawo żądania dostępu, sprostowania, usunięcia, ograniczenia, przeniesienia przetwarzania danych, złożenia sprzeciwu, złożenia skargi do organu nadzorczego na zasadach określonych w polityce prywatności.


Korzystanie z witryny bez zmiany ustawień Twojej przeglądarki oznacza, że pliki cookies będą umieszczane w Twoim urządzeniu końcowym. W celu zmiany ustawień prywatności możesz kliknąć w link Ustawienia zaawansowane lub "Ustawienia prywatności" znajdujący się w stopce każdego serwisu w ramach których będziesz mógł udzielić, odwołać zgodę lub w inny sposób zarządzać swoimi wyborami. Szczegółowe informacje na temat przetwarzania Twoich danych osobowych znajdziesz w polityce prywatności.