Windows Phone 7에는 현재 Dark/Light 이렇게 2개의 테마가 있는데 아래 코드는 이 2개의 테마를 구분하는 다양한 코드입니다.
// Use PhoneDarkThemeVisibility
Visibility visibilityDark = (Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"];
if (visibilityDark == Visibility.Visible)
{
    // Dark theme
}
else if (visibilityDark == Visibility.Collapsed)
{
    // Light theme
}

// Use PhoneLightThemeVisibility
Visibility visibilityLight = (Visibility)Application.Current.Resources["PhoneLightThemeVisibility"];
if (visibilityLight == Visibility.Collapsed)
{
    // Dark theme
}
else if (visibilityLight == Visibility.Visible)
{
    // Light theme
}

// Use PhoneLightThemeOpacity
double opacityDark = (double)Application.Current.Resources["PhoneDarkThemeOpacity"];
if (opacityDark == 1.0)
{
    // Dark theme
}
else if (opacityDark == 0.0)
{
    // Light theme
}

// Use PhoneLightThemeOpacity
double opacityLight = (double)Application.Current.Resources["PhoneLightThemeOpacity"];
if (opacityLight == 0.0)
{
    // Dark theme
}
else if (opacityLight == 1.0)
{
    // Light theme
}

// Use PhoneForegroundColor
Color colorForeground = (Color)Application.Current.Resources["PhoneForegroundColor"];
if (colorForeground.ToString() == "#FFFFFFFF")
{
    // Dark theme
}
else if (colorForeground.ToString() == "#DE000000")
{
    // Light theme
}

// Use PhoneBackgroundColor
Color colorBackground = (Color)Application.Current.Resources["PhoneBackgroundColor"];
if (colorBackground.ToString() == "#FF000000")
{
    // Dark theme
}
else if (colorBackground.ToString() == "#FFFFFFFF")
{
    // Light theme
}

Posted by Gungume
,
Windows Phone 7의 Theme는 Dark/Light 2개의 Background를 설정할 수 있고, 10개의 Accent color를 설정할 수 있습니다.

아래는 위의 값들을 얻어오는 방법과 각 값의 ARGB 색상정보입니다.

//Get background color
Color themeBackColor = (Color)Application.Current.Resources["PhoneBackgroundColor"];

//Get foreground color
Color themeForeColor = (Color)Application.Current.Resources["PhoneForegroundColor"];

//Get accent color
Color accentColor = (Color)Application.Current.Resources["PhoneAccentColor"];

Dark/Light theme에 따른 Background/Foreground 색상 정보
 Theme 종류  Background ARGB  Foreground ARGB
 Dark  #FF000000  #FFFFFFFF
 Light  #FFFFFFFF  #DE000000

Accent 색상 정보
 Accent color  ARGB
 magenta  #FFFF0097
 purple  #FFA200FF
 teal  #FF00ABA9
 lime  #FF8CBF26
 brown  #FFA05000
 pink  #FFE671B8
 orange  #FFF09609
 blue  #FF1BA1E2
 red  #FFE51400
 green  #FF339933


Posted by Gungume
,
Windows Phone 7 에뮬레이터에서 글씨를 입력하려면 기본적으로 SIP(Soft Input Panel)가 사용됩니다.

기존 Windows Mobile 6.5 에뮬레이터까지는 SIP와 상관없이 컴퓨터의 키보드를 이용해서 입력이 가능했는데 Windows Phone 7 에뮬레이터에서는 SIP 입력과 컴퓨터 키보드 입력이 토글로 설정됩니다.

SIP와 키보드간 토글은 Pause/Break키를 누를 때마다 변경됩니다. 즉, SIP가 뜬 상태에서 Pause/Break키를 누르면 SIP가 내려가는데 이때는 키보드를 이용해서 입력이 가능합니다.
( Pause/Break키 말고도 Page Up/Down 키를 이용해서 키보드를 On/Off 시킬 수 있습니다.)

키보드 입력 이외에 에뮬레이터에서 사용가능한 주요 키보드 키는 아래와 같습니다.
F1, F2, F3 : Windows Phone 7의 주요 하드웨어 키로서 각각 Back, Start, Search와 맵핑.
F7 : Camera 실행.
F9, F10 : Volume Up/Down

위에 언급한 것 이외에 다른 키와 자세한 정보는 아래 사이트에서 확인 가능합니다.

Keyboard Mapping for Windows Phone Emulator

Windows Phone 7 Emulator tips and tricks - Shortcut keys
Posted by Gungume
,
Windows Phone Developer Tools Beta를 설치하면 같이 설치되는 express 버전에서 개발을 하거나, vs2010 영문판을 이미 설치했다면 프로젝트 템플릿이 생성되므로 그것을 이용해서 개발이 가능합니다.

하지만 기본적으로 vs2010 한글판을 설치한 경우에는 Windows Phone Developer Tools Beta를 설치해도 템플릿이 나오지 않는데 아래 방법을 이용하면 vs2010 한글판에서도 Windows Phone 7 Beta 개발을 수행할 수 있습니다.
(아래에서 설명한 경로는 Windows 7 64bit에서 기본 설치경로로 설치했다는 가정하에서 설명합니다.)

1. 프로젝트 템플릿 생성
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Silverlight for Windows Phone\
위의 경로에 가시면 1033 이라는 폴더가 있는데 이것을 그대로 복사해서 폴더명을 1042로 변경합니다.

2. 아이템 템플릿 생성
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Silverlight for Windows Phone
위의 경로에 가시면 1033 이라는 폴더가 있는데 이것을 그대로 복사해서 폴더명을 1042로 변경합니다.

3. "시작 -> 모든 프로그램 -> Microsoft Visual Studio 2010 -> Visual Studio Tools -> Visual Studio 명령 프롬프트(2010)"를 실행 하면 나오는 명령 프롬프트 창에서 아래 2줄의 명령어 입력.
devenv.exe /installvstemplates 
devenv.exe /setup 

4. 실행했던 명령 프롬프트 종료 후에 Visual Studio 2010 한글판을 실행하면 아래 화면과 같이 템플릿이 추가된 것을 볼 수 있습니다.

ProjectTemplates

ProjectTemplates


ItemTemplates

ItemTemplates



Posted by Gungume
,
윈도우(Form)가 바탕화면 가장자리에 가까이 가면 자동으로 붙도록 만드는 것은 그다지 어렵지 않습니다.

현재 윈도우의 좌표가 바탕화면 가장자리 좌표와 일정 수준 이상 가깝게 되면 윈도우를 강제로 바탕화면 가장자리 근처로 이동시키는게 로직의 전부입니다.

그러나 C#의 기본 Form 이벤트는 윈도우가 이동이 완료된 후의 이벤트밖에 없습니다. 자석윈도우를 만들려면 윈도우가 이동중일 때의 이벤트가 필요한데 말이죠.

아래 코드는 별다른 로직은 없고 윈도우 메시지를 직접 받아서 처리하는 코드입니다.

간단히 코드를 설명하면 WndProc 함수를 오버라이드해서 WM_WINDOWPOSCHANGING(윈도우가 이동중) 메시지를 받습니다.

그리고 SetDockWindow() 함수를 호출하는데 첫번째 매개변수에는 자석윈도우로 만들 Form을 넘겨줍니다. 두번째 매개변수는 윈도우가 바탕화면 가장자리에 어느정도 가까이 가면 붙도록 할 것인지를 결정하는 수치로 픽셀단위의 정수형 값을 넘겨줍니다. 마지막 매개변수는 WndProc 함수에서 받은 Message 객체를 그대로 전달해줍니다.

SetDockWindow() 함수에서는 Screen.FromHandle()을 이용해서 현재 폼이 위치한 화면의 작업 영역을 얻어옵니다. 이렇게 함으로써 듀얼모니터 지원이 가능합니다.

나머지 코드들은 그냥 좌표 계산이 전부인데 Math.Abs() 함수를 써서 윈도우가 화면안에 있을때나 바깥에 있을 때 모두 자석효과가 가능하도록 처리해줍니다.

public const Int32 WM_WINDOWPOSCHANGING = 0x0046;

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
    public IntPtr hwnd;
    public IntPtr hwndInsertAfter;
    public int x;
    public int y;
    public int cx;
    public int cy;
    public int flags;
}
        
protected override void WndProc(ref Message m)
{
    switch(m.Msg)
    {
        case WM_WINDOWPOSCHANGING:
            SetDockWindow(this, 25, ref m);
            break;
    }
    base.WndProc(ref m);
}

private void SetDockWindow(Form form, int dockMargin, ref Message message)
{
    //현재 Form이 위치한 화면의 작업영역 가져옴(WorkingArea = 작업표시줄을 제외한 영역)
    Rectangle currentDesktopRect = (Screen.FromHandle(form.Handle)).WorkingArea;
            
    WINDOWPOS winPos = (WINDOWPOS)message.GetLParam(typeof(WINDOWPOS));

    //left
    if (Math.Abs(winPos.x - currentDesktopRect.Left) <= dockMargin)
    {
        winPos.x = currentDesktopRect.Left;
    }

    //top
    if (Math.Abs(winPos.y - currentDesktopRect.Top) <= dockMargin)
    {
        winPos.y = currentDesktopRect.Top;
    }

    //right
    if (Math.Abs(winPos.x + winPos.cx - currentDesktopRect.Left - currentDesktopRect.Width) <= dockMargin)
    {
        winPos.x = currentDesktopRect.Right - winPos.cx;
    }

    //bottom
    if (Math.Abs(winPos.y + winPos.cy - currentDesktopRect.Top - currentDesktopRect.Height) <= dockMargin)
    {
        winPos.y = currentDesktopRect.Bottom - form.Bounds.Height;
    }

    Marshal.StructureToPtr(winPos, message.LParam, false);
    message.Result = (IntPtr)0;
}
(사용언어 / 제작툴 / .Net Framework버전 : C# / VS2010 / 2.0)
Posted by Gungume
,
타블렛이나 터치스크린을 사용하면 마우스의 오른쪽버튼 기능을 위해서 롱프레스 기능을 제공합니다.

그러나 가끔은 자신만의 롱프레스 기능 구현을 위해서 이런 기본 기능을 꺼야 하는 경우가 있는데 이럴 때 아래 코드를 사용하면 됩니다.

사용법은 단순히 함수 호출하면서 롱프레스 기능을 끄고 싶은 폼(윈도우, 컨트롤)의 핸들을 첫번째 매개변수로 주고, 두번째 매개변수에 false를 주면 됩니다.(반대로 다시 켜고 싶으면 true를 주면 됩니다.)

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern ushort GlobalAddAtom(string lpString);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetProp(IntPtr hWnd, string lpString, IntPtr hData);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr RemoveProp(IntPtr hWnd, string lpString);

bool TogglePressAndHold(IntPtr hWnd, bool enable)
{
    ushort atomID = 0;
    string tabletAtom = "MicrosoftTabletPenServiceProperty";

    atomID = GlobalAddAtom(tabletAtom);

    if (atomID == 0)
    {
        return false;
    }

    if (enable)
    {
        IntPtr ptr = RemoveProp(hWnd, tabletAtom);
        if (ptr != null)
            return true;
    }
    else
    {
        return SetProp(hWnd, tabletAtom, new IntPtr(1));
    }
    return false;
}
위의 코드는 MSDN에 잇는 코드를 단순히 C#으로 컨버팅한 것입니다. 자세한 정보와 C++, VB 코드는 아래 MSDN을 참고하세요~
(http://msdn.microsoft.com/en-us/library/ms812373.aspx)

첨부파일은 위의 코드를 이용한 샘플 프로그램의 소스이고 그 실행 화면은 아래와 같습니다.
(체크박스의 체크여부에 따라서 폼 위에서 롱프레스 가능 여부가 결정됩니다.)



(사용언어 / 제작툴 / .Net Framework버전 : C# / VS2010 / 2.0)
Posted by Gungume
,
예전에 만들었던 파일날짜 일괄변경 프로그램(http://gungume.com/162)의 초기버전의 스크린샷을 보면 XP와 7에서의 레이아웃이 서로 틀린적이 있었습니다.

이것은 Form의 속성 중 AutoScaleMode와 관련된 것으로 AutoScaleMode는 화면 해상도나 글꼴에 따라서 폼이나 컨트롤의 크기를 자동으로 조절하는 기능입니다.

원래 이 속성은 Font, DPI 등이 다른 환경에서도 적절한 UI를 보여주기 위함인데 파일날짜 일괄변경 프로그램처럼 정확한 위치와 크기로 폼을 디자인할 때는 오히려 이 기능이 악영향을 미칩니다.

파일날짜 일괄변경 프로그램이 레이아웃이 깨졌던 이유는 AutoScaleMode가 Font로 설정되있고 Font는 굴림으로 설정되있는데 영문 윈도우에 해당 Font가 지원이 안되서 다른 Font로 설정되면서 레이아웃이 깨졌던 것입니다.

AutoScaleMode 속성의 기본 값은 Font인데 이 값을 None으로 설정해주면 어느 환경에서나 디자인한 그대로 레이아웃이 유지됩니다.

자세한 정보는 아래 MSDN을 참고하세요~

AutoScaleMode 열거형
http://msdn.microsoft.com/ko-kr/library/system.windows.forms.autoscalemode.aspx

Windows Forms의 자동 배율 조정
http://msdn.microsoft.com/ko-kr/library/ms229605.aspx
Posted by Gungume
,
XP타블렛 에디션, Vista, 7 등에서 터치 스크린이나 타블렛 등을 이용하면 해당 장치들은 마우스와 별도로 처리해주는 과정을 거쳐주면 좀더 깔끔한 프로그램을 만들수 있습니다.

단순히 깔끔한 처리를 넘어서 터치와 펜입력은 마우스와는 이벤트 발생 시점이 조금 틀리므로 이런 차이점을 고려해서 프로그램을 만들어줘야합니다.

대표적으로 차이가 나는 부분이 Down/Up 이벤트로 마우스는 버튼을 누르면 Down 이벤트가 발생하고, 버튼을 놓으면 Up이벤트가 발생합니다. 하지만 터치와 펜 입력은 버튼을 놓는 시점에 Down/Up 이벤트가 동시에 발생합니다.
(혹은 Down 후 Move시에 Down 이벤트 발생)

이런 차이점은 단순한 처리의 경우에는 별다른 문제점이 없습니다. 예를 들어서 버튼의 경우 터치/펜 이벤트도 어차피 Up 이벤트가 발생하는 순간에 Down 이벤트도 발생하므로 버튼이 눌렸다는 이벤트는 발생하므로 마우스와 마찬가지로 버튼의 눌린 것에 대한 이벤트 처리가 가능합니다.

그러나 다음의 경우에 대해서는 문제가 발생합니다.

직접 버튼 컨트롤을 만들고 버튼의 이미지를 Normal, Hover, Press 상태에 따라서 별도로 만들고 마우스/터치/펜 이벤트를 그냥 일반 마우스 이벤트로 처리한다면 마우스는 3가지 상태에 대해서 모두 정상 동작합니다.

하지만 터치/펜의 경우는 정상 동작을 하지 않습니다. 앞서 말했듯이 터치/펜은 Up이벤트가 발생해야 Down이벤트가 발생합니다. 즉 터치/펜을 이용해서 버튼을 누른채로 가만히 있다면 원래는 Press 이미지가 그려져야 하는데 터치/펜은 그 시점에 Down 이벤트가 발생하지 않으므로 Press 이미지를 그리지 못합니다.
(이런 문제점은 Vista, 7 등에서 기본 버튼 컨트롤 위에서도 발생합니다.)

MS에서는 이런 문제를 해결할 수 있도록 터치/펜에 대한 패킷데이터를 바로 받을 수 있는 방법을 제공하는데 Microsoft.Ink.Dll에 들어있는 RealTimeStylus가 그것입니다.

RealTimeStylus는 XP Tablet Edition을 위한 TabletSDK에 처음 들어있었고, 비스타(닷넷프레임워크 3.0)에서부터는 기본적으로 들어있습니다. 이것을 사용하면 패킷데이터를 바로 받을 수 있기 때문에 최종 결과물을 보면 일반 마우스처럼 동작하도록 만들 수 있고 단순히 위의 내용에 대한 해결방법외에 타블렛, 터치에 대한 다양한 정보를 얻을 수 있습니다.

참고로 Microsoft.Ink.Dll은 몇가지 버전이 있는데 단순히 위에 열거한 문제를 해결하기 위해서는 TabletSDK에 들어있는1.7버전을 사용해도 됩니다. 하지만 샘플에서는 마우스/터치/타블렛을 지원하는 코드를 포함하느라 비스타에 들어있는 6.0버전을 사용했습니다.
(참고로 7에 들어있는 6.1 버전은 멀티터치 관련한 내용도 들어있습니다.)

아래 링크는 TabletSDK와 Microsoft.Ink.Dll 버전 선택에 관한 MSDN 문서입니다.

RealTimeStylus의 간단한 샘플에 대한 코드는 다음 포스트에서 다루겠습니다.
Posted by Gungume
,


개인적으로 네이트온의 쪽지기능을 많이 싫어해서 만든 프로그램입니다.

싫어하는 이유는 많이 있겠지만 YUE님의 나는 네이트온 쪽지창을 싫어한다.(http://yue.co.kr/66)라는 글이 모든 것을 설명해주는 것 같습니다.

사용법은 간단합니다.

프로그램을 실행하면 위와 같은 화면이 나오는데 기본적으로는 "특정 사용자만 차단"이 해제되어 있고, 이것이 해제되어 있다면 모든 쪽지가 차단됩니다.

그리고 특정 사용자만 차단하고 싶다면 위의 화면과 같이 "특정 사용자만 차단" 버튼을 체크하고, 사용자 이름 입력 부분에 차단을 하고 싶은 사용자의 이름을 입력하고 엔터키를 누르거나 "사용자 추가" 버튼을 누르면 차단할 사용자가 추가됩니다.

프로그램 시작과 동시에 별다른 설정없이 바로 차단이 동작합니다. 그리고 프로그램의 X버튼을 누르면 자동으로 트레이로 이동됩니다.(프로그램 종료는 트레이에서 가능합니다.)

마지막으로 "특정 사용자만 차단" 체크여부와 추가된 사용자는 프로그램 종료시 자동으로 user.dat라는 파일에 저장되고 이 정보를 이용해서 다음 실행시 해당 정보를 이용해서 프로그램이 실행됩니다.

※ 네이트온 프로토콜 등을 분석해서 만든 것이 아니고 쪽지가 오면 바로 꺼버리는 방식으로 만들었으므로, 프로그램을 사용한다면 쪽지가 왔었는지 여부를 알 수 없으니 사용상의 주의 필요함.(메시지함에 직접 들어가면 확인 가능)

(사용언어 / 제작툴 / .Net Framework버전 : C# / VS2010 / 2.0)

※ 아이콘
Posted by Gungume
,
마우스 전역후킹(WH_MOUSE_LL)을 설치 후에 윈도우의 시스템버튼(최소화/최대화/닫기)을 누르면 딜레이가 생기는 경우가 있는데 이것을 해결하는 레지스트리 코드입니다.
(저는 XP에서 이 증상이 나오는데 검색을 해보니 Vista 이상의 OS에 대한 레지스트리 팁에 해당 내용이 있네요...)

레지스트리 경로
[HKEY_CURRENT_USER\Control Panel\Desktop]

설정값
(DWORD)LowLevelHooksTimeout=100
(값은 1/1000초 단위로 셋팅)


자세한 내용은 아래 MSDN을 참고하세요.
Posted by Gungume
,