Skip navigation.

云舒云卷

----我醉欲眠卿且去,明朝有意抱琴来

Enable vista style for common controls

, ,

In visual studio 2005, they are several ways to enable it, but all are related to manifest file.
  1. Create a manifest manually with following codes, and input its path to the 'project setting'->'Manifest tool'->'Input and output'->'Additional manifest files':
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0"
                processorArchitecture="X86"
                publicKeyToken="6595b64144ccf1df"
                language="*"
            />
        </dependentAssembly>
    </dependency>
    </assembly>

  2. Put the following code in the source file:
    #pragma comment(linker, "\"/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\"")
    

  3. Put the following code to 'project setting'->'liker'->'Manifest file'->'Additional Manifest Dependencies':
    "name='Microsoft.Windows.Common-Controls' processorArchitecture='x86' version='6.0.0.0' type='win32' publicKeyToken='6595b64144ccf1df'"
    


All in all, DO NOT put the following codes into 'project setting'->'Manifest tool'->'General'->'Assembly Identity':
Microsoft.Windows.Common-Controls, processorArchitecture=x86, version=6.0.0.0, type=win32, publicKeyToken=6595b64144ccf1df

HKM_SETHOTKEY (msdn tells wrong information)

,

In msdn, it says:

wParam
The LOWORD is the virtual key code of the hot key. The HIWORD is the key modifier that indicates the keys that define a hot key combination. ...



It is not the truth.

In HKM_GETHOTKEY Message, it says:

Returns the virtual key code and modifier flags. The virtual key code is in the low-order byte, and the modifier flags are in the high-order byte. ...



So, in the first phase, LOWORD and HIWORD must be LOBYTE and HIBYTE. If you trust the description in msdn, use MAKEWPARAM (instead of MAKEWORD) macro to build the parameter, your hot key control will only display the VK without the modifiers.

EDIT BOX:一行一行显示文本

,

Edit Box是VC中比较阳春的一个控件。当设置了Multiline属性之后,可以显示多行文本——或者更精确的说法是,可以用多行来显示文本。
一般简单的用法如下:
SetDlgItemText(g_hWnd, IDC_EDIT_CONTENT, _T("Hello\r\nWorld!"));


但是,无论是SetDlgItemText/SetWindowTExt/WM_SETTEXT,多无法以如下如下的步骤来实现多行文本:
SetDlgItemText(g_hWnd, IDC_EDIT_CONTENT, _T("Hello\r\n"));
SetDlgItemText(g_hWnd, IDC_EDIT_CONTENT, _T("World!"));


Edit Box不会显示两行文本,而是以第二行替换第一行。

我们可以子类化Edit Box,或是换其他的控件来实现这个功能。但是,其实这样的功能,只要稍微变通一下,Edit Box自身也是可以实现的。
SetDlgItemText(g_hWnd, IDC_EDIT_CONTENT, _T("Hello\r\n"));
int nLen = (int)_tcslen(_T("Hello\r\n"));
SendDlgItemMessage(g_hWnd, IDC_EDIT_CONTENT, EM_SETSEL, nLen, nLen + 1);
SendDlgItemMessage(g_hWnd, IDC_EDIT_CONTENT, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)_T("World!"));

使用EM_SETSELEEM_REPLACESEL就可以实现。
试试看!:smile:

_interlockedbittestandset prototype conflict

If you use vs2005 and platform sdk v6.0, maybe you will encounter a issue as,

c:\program files\microsoft visual studio 8\vc\include\intrin.h(944) :
error C2733: second C linkage of overloaded function '_interlockedbittestandset' not allowed
c:\program files\microsoft visual studio
8\vc\include\intrin.h(944) : see declaration of '_interlockedbittestandset'
c:\program files\microsoft visual studio 8\vc\include\intrin.h(945) :
error C2733: second C linkage of overloaded function '_interlockedbittestandreset' not allowed
c:\program files\microsoft visual studio
8\vc\include\intrin.h(945) : see declaration of '_interlockedbittestandreset'



This error raised because if you use platform sdk v6.0, they will be 4 versions of the function '_interlockedbittestandset',
  1. in vs2005\...\intrin.h
  2. in vs2005\...\winnt.h
  3. sdk v6.0\...\intrin.h
  4. sdk v6.0\...\winnt.h


the first 3 is OK, but in the 4th, MS added 'volatile' for the first parameter of the function,
it causes the issues.

the workaround is simple, like following,
#define _interlockedbittestandset fk_m$_set
#define _interlockedbittestandreset fk_m$_reset
#include <intrin.h>
#undef _interlockedbittestandset
#undef _interlockedbittestandreset

SetLayeredWindowAttributes to Edit only window will fail in non-Window Vista Basic color scheme

using following code to create "edit" control only window:
    HWND hwnd = CreateWindowEx (WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, 
                  _T("EDIT"), 
                  NULL/*szAppName*/, 
                  WS_POPUP | ES_CENTER,
                  CW_USEDEFAULT, 
                  CW_USEDEFAULT, 
                  CW_USEDEFAULT, 
                  CW_USEDEFAULT, 
                  NULL, 
                  NULL, 
                  hInstance,
                  NULL); 
    OrignalWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
    //ShowWindow (hwnd, iCmdShow);
    UpdateWindow (hwnd);
    //SetThemeAppProperties(0);
    SetLayeredWindowAttributes(hwnd, RGB(255, 0, 0), 200, LWA_ALPHA/* | LWA_COLORKEY*/);

Then, swich your color scheme from "Window Aero" to any others, like "Windows Vista Basic", you will notice that SetLayeredWindowAttributes will return 0, Last Error Code is 0 also.

Additional, a normal window is not effected after color sheme switched.

在资源管理器中显示应用程序的图标

一个应用程序想在windows的资源管理器中能够显示图标,需要满足以下几点:
  1. 图标为16色。
    直到vista,资源管理器中仍然只能显示16色的图标。如果你的图标大于16色,在资源管理器中显示的就是一个没有图标的程序。
  2. ID最小。
    在资源管理器中显示的图标,是在resource.h中id最小的那个。一般来说,也就是最先被创建的那个图标。

Vista下普通用户的环境变量

竟然没有发现哪里可以更改的。

想在system设置里面改,需要Admin的密码。输入后就是Admin了,没有普通用户的设置。

:down:

kmp(Knuth-Morris-Pratt)算法

分两个部分:
1. 子串预处理表
2. 搜索算法

子串W预处理表T[]的建立:
1. A为W的子串,并且其字首的子串和字尾的子串同为B。
2. W中字符,若其前面的所有字符构成子串A,则该字符在T中对应的值为最大B的字长。
3. 否则,该字符在T中对应的值为0
4. T[0] = -1, T[1] = 0

搜索算法:
1. i 为当前正在比较的字符在W中的位置(从0开始),j为主串S中开始比较的字符的位置
2. 若比较成功,则i+1
3. 若比较失败,S中下一次开始比较的位置为当前位置回退T,W中下一次开始比较的位置为0 (若上一次比较为失败),或是T(若上一次比较为成功)。
4.重复步骤2.

#include <iostream>
using namespace std;

#ifdef _UNICODE
#define  _tcout wcout
#else
#define  _tcout cout
#endif

void BuildKmpTable(TCHAR* psz_string, int kmp_table[])
{
    int n_len = _tcslen(psz_string);
    
    int n_str_index = 0;
    int n_table_index = 2;
    kmp_table[0] = -1;
    kmp_table[1] = 0; // self reference are assumed to be zero

    int n_prefix_len = 0;

    for (int i = n_table_index, j = n_str_index; i < n_len; )
    {
        // computer the value in the kmp_table[i]
        if (psz_string[i - 1] == psz_string[j])
        {
            n_prefix_len++;
            kmp_table[i] = n_prefix_len;
            j++;
            i++;
        }
        else
        {
             if (j > 0)
             {
                 j = kmp_table[j];
             }
             else
             {
                 kmp_table[i] = 0;
                 i++;
             }
        }
    }
}

int KmpSearch(TCHAR* psz_main, TCHAR* psz_sub)
{
    int n_sub_len = _tcslen(psz_sub);

    int* kmp_table = new int[n_sub_len];
    BuildKmpTable(psz_sub, kmp_table);

    int n_main_index = 0;
    int n_sub_index = 0;

    int n_main_len = _tcslen(psz_main);

    while ((n_main_index + n_sub_index) < n_main_len)
    {
        if (psz_main[n_main_index + n_sub_index] == psz_sub[n_sub_index])
        {
            n_sub_index++;
            if (n_sub_index == n_sub_len)
            {
                return n_main_index + 1;
            }
        }
        else
        {
            n_main_index += n_sub_index - kmp_table[n_sub_index];
            if (n_sub_index > 0)
            {
                n_sub_index = kmp_table[n_sub_index];
            }
        }
    }

    return -1;
}

int _tmain(int argc, _TCHAR* argv[])
{

    int n_index = KmpSearch(argv[1], argv[2]);

    _tcout << _T("search \"") << argv[2] << _T("\" in \"") << argv[1] << _T("\"") << endl;
    _tcout << _T("it matched in ") << n_index << endl;

return 0;
}

搬新地方了!

周五,公司换了个新地方。原指望空间能大一点,却不想个人的工作位反而更小!

我向来随遇而安,但也觉这次档次有所下降,不合公司的一惯宗旨和作风。不满的人不在少数!

不知公司这次如果安抚。如果只是画个饼,就太没诚意了!

Why must you use CallWindowProc to call the original proc?

When you are subclassing a window, in msdn, it is said you must use CallWindowProc to call the original window procedure instead of call the original procedure directly, because CallWindowProc will handles unicode wndproc to ansi wndproc.

If you use GetWindowLongPtr/SetWindowLongPtr to get/set the window procedure, you should keep in mind that there are two versions of the window procedures:
  1. one is ansi version,
  2. and the other unicode.

otherwise, you will get an address which starts with 0xFFFF~~~~.

I.E., Even if your application is unicode, if the original window procedure is ansi, you will get an ansi version of the window procedure and should feed an ansi version to it too.