Ciekawostki

Windows Phone 7 – porównanie urządzeń

Pewnego dnia siedząc przed komputerem i studiując lekturę dotyczącą Windows Phone 7 trafiłem na porównanie urządzeń pod względem rozmiarów, wagi, baterii, pamięci RAM/ROM itp. Niestety gdy chciałem jeszcze raz sięgnąć do tego zestawienia nie mogłem go znaleźć…
Przypadkiem porównanie ponownie wpadło mi w ręce, a właściwie pojawiło się na moim ekranie i tym razem, zamieszczam je na blogu. Robię to z dwóch powodów:
1 – w razie potrzeby będę wiedział gdzie szukać :)
2 – może komuś też się to przyda, lub kogoś zainteresuje

Windows Phone 7 comparision

Źródła:
ElectricForest
Microsoft News Center


Prawda o SqlCommand.Parameters

Czy zastanawialiście się kiedyś jak dodawać parametry do SqlCommand? Klasa ta zawiera pole Parameters typy SqlParameterCollection, na którym możemy wykonać między innymi metodę AddWithValue(string, object). W internecie jak i w dokumentacji w nazwach parametrów na początku jest zawsze użyty znak “@”.

Przy okazji jednego z projektów musiałem odpowiedzieć sobie na pytanie: Czy muszę zadbać o “@” przy nazwie parametru? Nie zastanawiając się długo postanowiłem, zgodnie duchem empiryzmu, sprawdzić co się stanie w poszczególnych sytuacjach.

Baza danych.

Dla testów mała baza danych z jedną procedurą pobierającą dwa parametry:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE DATABASE SqlCmdParametersTest
USE [SqlCmdParametersTest]
CREATE PROCEDURE [dbo].[spTest]
	@Param1 INT,
	@Param2 INT
AS
BEGIN
	SET NOCOUNT ON;
	SELECT
 		@Param1 Col1,
		@Param2 Col2END
GO
-- TEST
EXEC [dbo].[spTest] 1, 2
EXEC [dbo].[spTest] @Param1=1, @Param2=2
EXEC [dbo].[spTest] @Param2=1, @Param1=2

Aplikacja testowa

Teraz nie pozostaje nic innego jak przygotować małą aplikację konsolową, która skorzysta z tej procedury. Wiadomo, że podstawowym sposobem dodawania parametrów jest użycie “@” na początku nazwy, zatem będzie to pierwszy sposób użycia. Jako drugi przypadek weźmiemy parametr bez tego znaku. Czy to wszystkie możliwości? Nie – można to przecież jeszcze połączyć i użyć raz z “@” a raz bez – ot tak, żeby było trudniej. Zatem do dzieła:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Data;
using System.Data.SqlClient;
 
namespace SqlCmdParametersTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection sqlConn = new SqlConnection(@"Data Source=localhost;Initial Catalog=SqlCmdParametersTest;Integrated Security=SSPI;Persist Security Info=true"))
            {
                sqlConn.Open();
                using (SqlCommand sqlCmd = new SqlCommand())
                {
                    sqlCmd.CommandType = CommandType.StoredProcedure;
                    sqlCmd.Connection = sqlConn;
                    sqlCmd.CommandText = "[dbo].[spTest]";
 
                    //call with @
                    Console.WriteLine("With @");
                    sqlCmd.Parameters.Clear();
                    sqlCmd.Parameters.AddWithValue("@Param1", 1);
                    sqlCmd.Parameters.AddWithValue("@Param2", 2);
                    using (SqlDataReader reader = sqlCmd.ExecuteReader())
                    {
                        ReadResult(reader);
                    }
 
                    //call without @
                    Console.WriteLine("Without @");
                    sqlCmd.Parameters.Clear();
                    sqlCmd.Parameters.AddWithValue("Param1", 1);
                    sqlCmd.Parameters.AddWithValue("Param2", 2);
                    using (SqlDataReader reader = sqlCmd.ExecuteReader())
                    {
                        ReadResult(reader);
                    }
 
                    //call mixed
                    Console.WriteLine("Mixed");
                    sqlCmd.Parameters.Clear();
                    sqlCmd.Parameters.AddWithValue("@Param1", 1);
                    sqlCmd.Parameters.AddWithValue("Param2", 2);
                    using (SqlDataReader reader = sqlCmd.ExecuteReader())
                    {
                        ReadResult(reader);
                    }
                }
            }
 
            Console.ReadLine();
        }
 
        private static void ReadResult(SqlDataReader reader)
        {
            if (reader.Read())
            {
                Console.WriteLine("Result:");
                Console.WriteLine("{0} {1}", reader["Col1"], reader["Col2"]);
            }
            else
            {
                Console.WriteLine("Result is empty");
            }
        }
    }
}

Wynik dziąłania aplikacji widać na rysunku poniżej:

SqlCmdParametersTestResult

Jak widać wynik jest zgodny z oczekiwaniami – wszystko działa poprawnie, nawet “mix”. Warto jeszcze sprawdzić co dociera do SQL Servera, bo może to on jest tą “sprytną stroną”… Po uruchomieniu SQL Profilera widzimy, że jednak krok ku wygodzie a przede wszystkim swobodzie jest po stronie .NET Framework.

SqlCmdParametersTestSqlProfiler

Wniosek

Z SqlCommand.Parameters można korzystać swobodnie i bez martwienia się o “@” lub jej brak.

Paczka do pobrania


Załączników ciąg dalszy…

Jakiś czas temu pisałem o miłym zaskoczeniu dotyczącym załączników w Thunderbird. Dziś tak się złożyło, że skorzystałem z mojej poczty przez stronę i moje zaskoczenie było równie duże. Okazuje się bowiem, że GMAIL rownież zna słowa związane z załącznikami i potrafi nas o tym poinformować:

gmail attachment info

Podobnie sprawa wygląda w przypadku słowa “załączam”. Niestety machanizm nie działa dla np “przesyłam” i “załącznik” – te drugie moim zdaniem powinno się znaleźć na liście rozpoznawanych słów…

Werdykt – nie jest źle, ale mogłoby być lepiej :)


Na dobry początek tygodnia – Productivity Power Tools

Jest poniedziałek rano, jak zawsze na początek tygodnia “prasówka” po ulubionych portalach tematycznych. Aby z tej okazji dać wam do przeczytania coś ciekawego postanowiłem zabrać się za Productivity Power Tools a dokładniej to, na co niewiele osób zwraca uwagę. Wszyscy rozpisują się o tym jak fajnie jest mieć dodatki, które PPT w sobie ma takie jak:

– podświetlanie aktywnej linii

– przypinanie i kolorowanie zkaładek oraz oznaczanie niezapisanych plików (czerwona kropka na zakładce)

– nakładka na dodawanie referencji pozwalająca je grupować i filtrować

– solution navigator, który pozwala szybciej poruszać się po logicznej zawartości solucji oraz pozwala na filtrowanie po nazwach, ale i stanach plików (otwarty, niezapysany itp)

– zaznaczanie całej linii potrójnym kliknięciem

– kombinacja Ctrl + Klik przenosi do definicji obiektu – w zastępstwie za F12 – zależy

– automatyczne domykanie nawiasów i tego typu dwuznaków (np cudzysłowy) – do tej funkcji trzeba się przyzwyczaić, gdyż na początku pojawia się nam ich nadmiar jeżeli domykamy je sami automatycznie :)

– wiele wiele innych…

Owszem – te dodatki są przydatne, ale NIE KAŻDY wie o tym co moim zdaniem jest najciekawsze! Chodzi tu mianowicie o okienko pomocy komend (Quick Access). Uruchamiamy je skrótem Ctrl + 3. Dlaczego jest ono moim zdaniem takie pomocne? Visual Studio posiada wbudowane ponad 4000 komend – tak twierdził na MTS 2010 Chris Granger z teamu Visual Studio. Nie wyobrażam sobie zapamiętania ich wszystkich, a nawet 10%. Przyznaję, że 1% jest jeszcze realny, ale gdzie tu do wykorzystania możliwości środowiska. Jeżeli korzystam z czegoś w 1%, to trzeba się zastanowić co zrobić, by zwiększyć ten współczynnik… Quick Access podpowiada możliwe komendy na podstawie wpisanej przez nas frazy. Wybraną opcję możemy zatwierdzić klawiszem Enter, co dodatkowo przyspiesza korzystanie z tej opcji. Dzięki temu nie ma konieczności pamiętania skrótów klawiaturowych (o ktorych pisałem w jednym z wcześniejszych postów), opcji włączania i wyłączania dodatkowych okien itp itd. Jedyne co jest potrzebne to świadomość istnienia pewnych możliwości i zwerbalizowanie ich w Quick Access. Dzięki temu osiągnięcie 10% (a nawet i więcej) wykorzystania możliwych (i pomocnych w pracy) komend staje się bardziej realna, a dodatkowo nie jest uciążliwą pamięciówką.

Productivity Power Tools można pobrać za darmo ze stron Visual Studio Gallery.


Thunderbird i załączniki – ciekawostka

Pisząc kolejnego dziś maila zacząłem od treści nawiązującej do załączników, których jeszcze nie dodałem. Zdziwiony byłem w momencie gdy Thunderbird poinformował mnie o tym fakcie i zaproponował ich dodanie…

ThunderbirdTip


Skróty klawiaturowe Visual Studio

To do czego wszyscy dążymy w naszej do wygody. Na wygodę składa się też szybkość tworzenia kodu – która jest głównym celem biznesu – im szybciej możesz kodować(*), tym szybciej skończysz projekt i tym szybciej zaczniesz kolejny.
(*) przy tym samym poziomie jakości kodu

W tym celu niezbędne wręcz jest zapoznanie się przynajmniej z podstawowymi skrótami dostępnymi w Visual Studio. Na MTS 2010 podczas sesji Chrisa Grangera na temat Visual Studio 2010 IDE Tips & Tricks można było usłyszeć, że najnowszy produkt posiada ponad 4000 komend (w tym skrótów klawiaturowych). Oczywiście nie jest możliwe poznanie wszystkich, jednakże te podstawowe warto sobie zapamiętać.

Dla zwolenników zapamiętywania wzrokowego Microsoft przygotował zestawienie takich skrótów w formie PDF – gotowych do wydrukowania. Polecam te dla Visual Studio 2010 i dla Visual Studio 2008

Moje top shostcuts to:

Shift + Ctrl + B Build
F5 Debug
Ctrl + . Zamiast Shift + Ctrl + F10 – “auto using”
F7 Kod C#
Shift + F7 Designer
Ctrl + D, I Immediate Window
Ctrl + W, S Solution Explorer
Ctrl + K, C Komentuj
Ctrl + K, U Odkomentuj
F12 Definicja medoty/klasy…

i wiele innych, które konsekwentnie poznaję :)


Problem z HttpCookie.Expires i jQuery

Dziś na temat korzystania z jQuery i ciasteczek. Jako scenariusz przyjmijmy proste zliczenie kliknięć, gdzie licznik przechowujemy jako wartość ciastka.

W tym celu tworzymy aplikację ASP.NET MVC wraz z testowym kontrolerem i dwoma widokami – Indeks, który jest widokiem bazowym i Modify, który zwraca kawałek html’a z zawartością ciastka.

Kotroler inicjujemy w następujący sposób:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Web;
  5 using System.Web.Mvc;
  6
  7 namespace CookieAndJQuery.Controllers
  8 {
  9     [HandleError]
10     public class TestsController : Controller
11     {
12         private static string CookieName = “TestCookie”;
13
14         public ActionResult Index()
15         {
16             return View();
17         }
18
19         public ActionResult Modify()
20         {
21             HttpCookie cookie = Request.Cookies[CookieName];
22             if (cookie == null)
23             {
24                 cookie = new HttpCookie(CookieName, “0”);
25                 cookie.Expires = DateTime.MaxValue;
26             }
27
28             int v = int.Parse(cookie.Value);
29             cookie.Value = (++v).ToString();
30             Response.Cookies.Add(cookie);
31             ViewData[“itemValue”]= cookie.Value;
32             return View();
33         }
34     }
35 }

Indeks ma za zadanie po kliknięciu przycisku wywołać akcję Modify w kontrolerze TestsController a następnie wstrzyknąć jej wynik do diva o id=”resultContainer”

  1 <%@ Page Language=“C#” Inherits=“System.Web.Mvc.ViewPage” %>
  2 <html>
  3 <head runat=“server”>
  4     <title>Index</title>
  5     <script src=“Scripts/jquery-1.4.1.min.js” type=“text/javascript”></script>
  6 </head>
  7 <body>
  8     <div>
  9         <input type=“button” id=“btnTestCookies” value=“ClickMe” />
10         <div id=“resultContainer”></div>
11     </div>
12     <script type=“text/javascript”>
13         $(“#btnTestCookies”).click(function () {
14             $.ajax(
15                 {
16                     url: “/Tests/Modify”,
17                     success: function (data) {
18                         $(“#resultContainer”).html(data);
19                     },
20                     cache: false,
21                     dataType: “html”
22                 }
23             );
24         });
25     </script>
26 </body>
27 </html>

 

Dla pełnego obrazu poniżej widnieje zawartość widoku Modify:

  1 <%@ Page Language=“C#” Inherits=“System.Web.Mvc.ViewPage” Buffer=“false” %>
  2 <div>
  3     <%= ViewData[“itemValue”] %>
  4 </div>

Skoro mamy już bazę do doświadczeń pora przejść do sedna problemu, a mianowiscie do obsługi ciastek. Jak zapewne zauważyliście kontroler w linii 25 ustawia czas wygaśnięcia ciastka na DateTime.MaxValue, czyli ciastko nigdy nie wygaśnie. Na pierwszy rzut oka nie widać problemu: wywołujemy akcję, akcja zmienia wartość ciastka, ciastko wraca do przeglądarki, klikamy ponownie, wartość wzrasta – super! Jednakże spójżmy jak faktycznie wygląda ciastko, które otrzymujemy:

Pierwsze wywołanie strony – tworzymy ciastko

Kolejne wywołanie strony – niestety jak widać poniżej czas wygaśnięcia ciastka przypadnie na koniec sesji:

Przez to po zamknięciu i ponownym uruchomieniu przeglądarki ciastko zostanie usuniete a tym samym licznik zostanie zresetowany…

Przyjrzyjmy się jak wygląda request i response. Korzystając z Fiddlera można podejrzeć treść nagłówka Cookies, w którym widać wszystko jak na dłoni:

Odpowiedź po pierwszym wywołaniu (ustawiamy ciastko)

Request przy kojelnych kliknięciach przycisku – jak widać brak przy żądaniu informacji o ekspiracji ciastka, co skuktuje opisanym zachowaniem.

Jak to ominąć? W przypadku, który miałem jako zadanie postanowiłem przy każdym takim wywołaniu ustawiać czas życia ciastka na DateTime.MaxValue, dzięki  czemu po ponownym uruchomieniu przeglądarki ciastko nadal tam jest…

  1 public ActionResult Modify()
  2 {
  3     HttpCookie cookie = Request.Cookies[CookieName];
  4     if (cookie == null)
  5     {
  6         cookie = new HttpCookie(CookieName, “0”);
  7         cookie.Expires = DateTime.MaxValue;
  8     }
  9
10     cookie.Expires = DateTime.MaxValue;
11     int v = int.Parse(cookie.Value);
12     cookie.Value = (++v).ToString();
13     Response.Cookies.Add(cookie);
14     ViewData[“itemValue”] = cookie.Value;
15     return View();
16 }

W wyniku tej modyfikacji informacja o ciastkach znajdująca się w odpowiedzi wygląda następująco

dzięki czemu przy kolejnym uruchomieniu przeglądarki ciastko nadal tam będzie gotowe do użycia :)


Przeklikaj swój świat! – kontrola zdarzeń myszki

Myszka – z pozoru urządzenie, które bez ludzkiej ręki nie jest w stanie nic zrobić. Błąd! Istnieje możliwość nadania jej “życia” poprzez wywoływanie odpowiednich zdarzeń z kodu aplikacji. Aby to osiągnąć przydatne może być wykorzystanie poniższego helpera, a właściwie szablonu helpera, który można w łatwy sposób rozszerzyć o kolejne metody:

  1 using System.Drawing;
  2 using System.Runtime.InteropServices;
  3 using System.Windows.Forms;
  4
  5 namespace ConsAppClicker
  6 {
  7     public static class MouseHelper
  8     {
  9         #region Internal
10         [DllImport(“user32.dll”, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
11         private static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
12
13         private const int MOUSEEVENTF_LEFTDOWN = 0x02;
14         private const int MOUSEEVENTF_LEFTUP = 0x04;
15         private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
16         private const int MOUSEEVENTF_RIGHTUP = 0x10;
17         #endregion
18
19         #region LMB
20         public static void RaiseDoubleClick()
21         {
22             int x = Cursor.Position.X;
23             int y = Cursor.Position.Y;
24             RaiseLeftClick(x, y);
25             RaiseLeftClick(x, y);
26         }
27
28         public static void RaiseLeftClick()
29         {
30             int x = Cursor.Position.X;
31             int y = Cursor.Position.Y;
32             RaiseLeftClick(x, y);
33         }
34
35 private static void RaiseLeftClick(int x, int y)
36 {
37     mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0);
38 }
39         #endregion
40
41         #region RMB
42         public static void RaiseRightClick()
43         {
44             int x = Cursor.Position.X;
45             int y = Cursor.Position.Y;
46             RaiseRightClick(x, y);
47         }
48
49         public static void RaiseRightClick(int x, int y)
50         {
51             mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, x, y, 0, 0);
52         }
53         #endregion
54
55         #region Position
56         public static void SetPosition(int x, int y)
57         {
58             Cursor.Position = new Point(x, y);
59         }
60         #endregion
61     }
62 }
63

Oferuje on możliwość ustawienia odpowiedniej pozycji kursora myszy oraz wywołania najważniejszych jej zdarzeń dla aktualnej pozycji. Jak widać przy pomocy PInvoke możemy wykorzystać wywołanie zdarzenia znajdujące się w bibliotece user32.dll, która przyjmuje flagę zdarzenia (bitowa flaga, lub ich suma) oraz współrzędne zdarzenia. Eksperymentując z tym helperem w
pewnym momencie zapewne zauważycie, że zdarzenie jest uruchamiane dla aktualnej pozycji kursora niezależnie od tego co jest podane w linii 51 (wywołanie mouse_event)… Dziwne zachowanie, być może zależy od czynników, do których jeszcze nie dotarłem podczas drążenia tematu. W związku z tym można by korzystać tylko z metody SetPosition oraz ze zmienionej postaci Raise*Click, na przykład:

  1 public static void RaiseRightClick(int x, int y)
  2 {
  3     mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
  4 }
 

Oto przykład wykorzystania, który przy domyślnych ustawieniach pulpitu i ikon (“Mój” komputer” w lewym gornym rogu) po dwóch sekundach od uruchomienia otworzy okno eksploratora plików.

  1 using System;
  2
  3 namespace ConsAppClicker
  4 {
  5     class Program
  6     {
  7         static void Main(string[] args)
  8         {
  9             Console.WriteLine(“Console mouse click demo”);
10             System.Threading.Thread.Sleep(2000);
11             MouseHelper.SetPosition(20, 20);
12             MouseHelper.RaiseDoubleClick();
13             Console.WriteLine(“Done!”);
14             Console.ReadLine();
15         }
16     }
17 }
 

Teraz ożywienie poczciwego “szczura” jest już w zasięgu ręki. Miłej zabawy!


Rysunkowe wyjaśnienie systemu motywacji

Oryginalne w swojej formie przemyślenia dotyczące systemów motywacji. Początkowo znalezione na antyweb.pl. Zgodzę się z Grzegorzem – fenomenalne podsumowanie dotyczące wolontariatu dla dobra wspólnego :)

Więcej tego typu filmów można znaleźć na stronie RSA Comment.


Stackoverflow – programming jargon czyli jak zrozumieć niektóre określenia ludzi z branży IT :)

“Pockemon Exception Handling”, “Yoda conditions” (przeurocza nazwa :) ), “Stringly Typed”, “Egiptian brackets”, “Workaroundability” to tylko niektóre z określeń, które odzwierciedlają kod. Polecam lekturę wszystkich określeń, ich definicji i przykładów – jeżeli znajdziesz tam coś znajomego – będziesz wiecieć jak to nazwać :)

UWAGA! Podczas czytania mogą wystąpić gwałtowne napady śmiechu – zanim zaczniesz uprzedź otoczenie!

http://stackoverflow.com/questions/2349378/new-programming-jargon-you-coined


  • O mnie

    Maciej Grabek

    Moje profile na:

    MVP

    Codeguru.pl GoldenLine
    Twitter CodeProject

  • english version
  • Polecam

  • Copyright © Maciej Grabek. All rights reserved.
    Powered by WordPress
    %d bloggers like this: