/* Unit test suite for status control.
 *
 * Copyright 2007 Google (Lei Zhang)
 * Copyright 2007 Alex Arazi
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>
#include <windows.h>
#include <commctrl.h>

#include "wine/test.h"

#define SUBCLASS_NAME "MyStatusBar"

#define expect(expected,got) ok (expected == got,"Expected %d, got %d\n",expected,got)
#define expect_rect(_left,_top,_right,_bottom,got) do { \
        RECT exp = {abs(got.left - _left), abs(got.top - _top), \
                    abs(got.right - _right), abs(got.bottom - _bottom)}; \
        ok(exp.left <= 2 && exp.top <= 2 && exp.right <= 2 && exp.bottom <= 2, \
           "Expected rect {%d,%d, %d,%d}, got {%d,%d, %d,%d}\n", \
           _left, _top, _right, _bottom, \
           (got).left, (got).top, (got).right, (got).bottom); } while (0)

static HINSTANCE hinst;
static WNDPROC g_status_wndproc;
static RECT g_rcCreated;
static HWND g_hMainWnd;
static int g_wmsize_count = 0;
static INT g_ysize;
static INT g_dpisize;
static int g_wmdrawitm_ctr;
static WNDPROC g_wndproc_saved;

static HWND create_status_control(DWORD style, DWORD exstyle)
{
    HWND hWndStatus;

    /* make the control */
    hWndStatus = CreateWindowEx(exstyle, STATUSCLASSNAME, NULL, style,
        /* placement */
        0, 0, 300, 20,
        /* parent, etc */
        NULL, NULL, hinst, NULL);
    assert (hWndStatus);
    return hWndStatus;
}

static LRESULT WINAPI create_test_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret;

    if (msg == WM_CREATE)
    {
        CREATESTRUCT *cs = (CREATESTRUCT *)lParam;
        ret = CallWindowProc(g_status_wndproc, hwnd, msg, wParam, lParam);
        GetWindowRect(hwnd, &g_rcCreated);
        MapWindowPoints(HWND_DESKTOP, g_hMainWnd, (LPPOINT)&g_rcCreated, 2);
        ok(cs->x == g_rcCreated.left, "CREATESTRUCT.x modified\n");
        ok(cs->y == g_rcCreated.top, "CREATESTRUCT.y modified\n");
    } else if (msg == WM_SIZE)
    {
        g_wmsize_count++;
        ret = CallWindowProc(g_status_wndproc, hwnd, msg, wParam, lParam);
    }
    else
        ret = CallWindowProc(g_status_wndproc, hwnd, msg, wParam, lParam);

    return ret;
}

static void register_subclass(void)
{
    WNDCLASSEX cls;

    cls.cbSize = sizeof(WNDCLASSEX);
    GetClassInfoEx(NULL, STATUSCLASSNAME, &cls);
    g_status_wndproc = cls.lpfnWndProc;
    cls.lpfnWndProc = create_test_wndproc;
    cls.lpszClassName = SUBCLASS_NAME;
    cls.hInstance = NULL;
    ok(RegisterClassEx(&cls), "RegisterClassEx failed\n");
}

static void test_create(void)
{
    RECT rc;
    HWND hwnd;

    ok((hwnd = CreateWindowA(SUBCLASS_NAME, "", WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0, 0, 100, 100,
        g_hMainWnd, NULL, NULL, 0)) != NULL, "CreateWindowA failed\n");
    MapWindowPoints(HWND_DESKTOP, g_hMainWnd, (LPPOINT)&rc, 2);
    GetWindowRect(hwnd, &rc);
    MapWindowPoints(HWND_DESKTOP, g_hMainWnd, (LPPOINT)&rc, 2);
    expect_rect(0, 0, 100, 100, g_rcCreated);
    expect(0, rc.left);
    expect(672, rc.right);
    expect(226, rc.bottom);
    /* we don't check rc.top as this may depend on user font settings */
    DestroyWindow(hwnd);
}

static int CALLBACK check_height_font_enumproc(ENUMLOGFONTEX *enumlf, NEWTEXTMETRICEX *ntm, DWORD type, LPARAM lParam)
{
    HWND hwndStatus = (HWND)lParam;
    HDC hdc = GetDC(NULL);
    static const int sizes[] = { 6,  7,  8,  9, 10, 11, 12, 13, 15, 16,
                                20, 22, 28, 36, 48, 72};
    DWORD i;
    INT y;
    LPSTR facename = (CHAR *)enumlf->elfFullName;

    /* on win9x, enumlf->elfFullName is only valid for truetype fonts */
    if (type != TRUETYPE_FONTTYPE)
        facename = enumlf->elfLogFont.lfFaceName;

    for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
    {
        HFONT hFont;
        TEXTMETRIC tm;
        HFONT hCtrlFont;
        HFONT hOldFont;
        RECT rcCtrl;

        enumlf->elfLogFont.lfHeight = sizes[i];
        hFont = CreateFontIndirect(&enumlf->elfLogFont);
        hCtrlFont = (HFONT)SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE);
        hOldFont = SelectObject(hdc, hFont);

        GetClientRect(hwndStatus, &rcCtrl);
        GetTextMetrics(hdc, &tm);
        y = tm.tmHeight + (tm.tmInternalLeading ? tm.tmInternalLeading : 2) + 4;

        ok( (rcCtrl.bottom == max(y, g_ysize)) || (rcCtrl.bottom == max(y, g_dpisize)),
            "got %d (expected %d or %d) for %s #%d\n",
            rcCtrl.bottom, max(y, g_ysize), max(y, g_dpisize), facename, sizes[i]);

        SelectObject(hdc, hOldFont);
        SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hCtrlFont, TRUE);
        DeleteObject(hFont);
    }
    ReleaseDC(NULL, hdc);
    return 1;
}

static int CALLBACK check_height_family_enumproc(ENUMLOGFONTEX *enumlf, NEWTEXTMETRICEX *ntm, DWORD type, LPARAM lParam)
{
    HDC hdc = GetDC(NULL);
    enumlf->elfLogFont.lfHeight = 0;
    EnumFontFamiliesEx(hdc, &enumlf->elfLogFont, (FONTENUMPROC)check_height_font_enumproc, lParam, 0);
    ReleaseDC(NULL, hdc);
    return 1;
}

static void test_height(void)
{
    LOGFONT lf;
    HFONT hFont, hFontSm;
    RECT rc1, rc2;
    HWND hwndStatus = CreateWindow(SUBCLASS_NAME, NULL, WS_CHILD|WS_VISIBLE,
        0, 0, 300, 20, g_hMainWnd, NULL, NULL, NULL);
    HDC hdc;

    GetClientRect(hwndStatus, &rc1);
    hFont = CreateFont(32, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Tahoma");

    g_wmsize_count = 0;
    SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE);
    if (!g_wmsize_count)
    {
        skip("Status control not resized in win95, skipping broken tests.\n");
        return;
    }
    ok(g_wmsize_count > 0, "WM_SETFONT should issue WM_SIZE\n");

    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 42, rc2); /* GetTextMetrics returns invalid tmInternalLeading for this font */

    g_wmsize_count = 0;
    SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE);
    ok(g_wmsize_count > 0, "WM_SETFONT should issue WM_SIZE\n");

    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 42, rc2);

    /* minheight < fontsize - no effects*/
    SendMessage(hwndStatus, SB_SETMINHEIGHT, 12, 0);
    SendMessage(hwndStatus, WM_SIZE, 0, 0);
    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 42, rc2);

    /* minheight > fontsize - has an effect after WM_SIZE */
    SendMessage(hwndStatus, SB_SETMINHEIGHT, 60, 0);
    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 42, rc2);
    SendMessage(hwndStatus, WM_SIZE, 0, 0);
    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 62, rc2);

    /* font changed to smaller than minheight - has an effect */
    SendMessage(hwndStatus, SB_SETMINHEIGHT, 30, 0);
    expect_rect(0, 0, 672, 62, rc2);
    SendMessage(hwndStatus, WM_SIZE, 0, 0);
    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 42, rc2);
    hFontSm = CreateFont(9, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Tahoma");
    SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFontSm, TRUE);
    GetClientRect(hwndStatus, &rc2);
    expect_rect(0, 0, 672, 32, rc2);

    /* test the height formula */
    ZeroMemory(&lf, sizeof(lf));
    SendMessage(hwndStatus, SB_SETMINHEIGHT, 0, 0);
    hdc = GetDC(NULL);

    /* used only for some fonts (tahoma as example) */
    g_ysize = GetSystemMetrics(SM_CYSIZE) + 2;
    if (g_ysize & 1) g_ysize--;     /* The min height is always even */

    g_dpisize = MulDiv(18, GetDeviceCaps(hdc, LOGPIXELSY), 96) + 2;
    if (g_dpisize & 1) g_dpisize--; /* The min height is always even */


    trace("dpi=%d (min height: %d or %d) SM_CYSIZE: %d\n",
            GetDeviceCaps(hdc, LOGPIXELSY), g_ysize, g_dpisize,
            GetSystemMetrics(SM_CYSIZE));

    EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)check_height_family_enumproc, (LPARAM)hwndStatus, 0);
    ReleaseDC(NULL, hdc);

    DestroyWindow(hwndStatus);
    DeleteObject(hFont);
    DeleteObject(hFontSm);
}

static void test_status_control(void)
{
    HWND hWndStatus;
    int r;
    int nParts[] = {50, 150, -1};
    int checkParts[] = {0, 0, 0};
    int borders[] = {0, 0, 0};
    RECT rc;
    CHAR charArray[20];
    HICON hIcon;
    char ch;
    char chstr[10] = "Inval id";
    COLORREF crColor = RGB(0,0,0);

    hWndStatus = create_status_control(WS_VISIBLE | SBT_TOOLTIPS, 0);

    /* Divide into parts and set text */
    r = SendMessage(hWndStatus, SB_SETPARTS, 3, (LPARAM)nParts);
    expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)"First");
    expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"Second");
    expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_SETTEXT, 2, (LPARAM)"Third");
    expect(TRUE,r);

    /* Get RECT Information */
    r = SendMessage(hWndStatus, SB_GETRECT, 0, (LPARAM)&rc);
    expect(TRUE,r);
    expect(2,rc.top);
    /* The rc.bottom test is system dependent
    expect(22,rc.bottom); */
    expect(0,rc.left);
    expect(50,rc.right);
    r = SendMessage(hWndStatus, SB_GETRECT, -1, (LPARAM)&rc);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_GETRECT, 3, (LPARAM)&rc);
    expect(FALSE,r);
    /* Get text length and text */
    r = SendMessage(hWndStatus, SB_GETTEXTLENGTH, 2, 0);
    expect(5,LOWORD(r));
    expect(0,HIWORD(r));
    r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray);
    ok(strcmp(charArray,"Third") == 0, "Expected Third, got %s\n", charArray);
    expect(5,LOWORD(r));
    expect(0,HIWORD(r));

    /* Get parts and borders */
    r = SendMessage(hWndStatus, SB_GETPARTS, 3, (LPARAM)checkParts);
    ok(r == 3, "Expected 3, got %d\n", r);
    expect(50,checkParts[0]);
    expect(150,checkParts[1]);
    expect(-1,checkParts[2]);
    r = SendMessage(hWndStatus, SB_GETBORDERS, 0, (LPARAM)borders);
    ok(r == TRUE, "Expected TRUE, got %d\n", r);
    expect(0,borders[0]);
    expect(2,borders[1]);
    expect(2,borders[2]);

    /* Test resetting text with different characters */
    r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)"First@Again");
    expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"Invalid\tChars\\7\7");
        expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_SETTEXT, 2, (LPARAM)"InvalidChars\\n\n");
        expect(TRUE,r);

    /* Get text again */
    r = SendMessage(hWndStatus, SB_GETTEXT, 0, (LPARAM) charArray);
    ok(strcmp(charArray,"First@Again") == 0, "Expected First@Again, got %s\n", charArray);
    expect(11,LOWORD(r));
    expect(0,HIWORD(r));
    r = SendMessage(hWndStatus, SB_GETTEXT, 1, (LPARAM) charArray);
    ok(strcmp(charArray,"Invalid\tChars\\7 ") == 0, "Expected Invalid\tChars\\7 , got %s\n", charArray);

    expect(16,LOWORD(r));
    expect(0,HIWORD(r));
    r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray);
    ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray);

    expect(15,LOWORD(r));
    expect(0,HIWORD(r));

    /* test more nonprintable chars */
    for(ch = 0x00; ch < 0x7F; ch++) {
        chstr[5] = ch;
        r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)chstr);
        expect(TRUE,r);
        r = SendMessage(hWndStatus, SB_GETTEXT, 0, (LPARAM)charArray);
        /* substitution with single space */
        if (ch > 0x00 && ch < 0x20 && ch != '\t')
            chstr[5] = ' ';
        ok(strcmp(charArray, chstr) == 0, "Expected %s, got %s\n", chstr, charArray);
    }

    /* Set background color */
    crColor = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, RGB(255,0,0));
    ok(crColor == CLR_DEFAULT ||
       broken(crColor == RGB(0,0,0)), /* win95 */
       "Expected 0x%.8x, got 0x%.8x\n", CLR_DEFAULT, crColor);
    crColor = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, CLR_DEFAULT);
    ok(crColor == RGB(255,0,0) ||
       broken(crColor == RGB(0,0,0)), /* win95 */
       "Expected 0x%.8x, got 0x%.8x\n", RGB(255,0,0), crColor);

    /* Add an icon to the status bar */
    hIcon = LoadIcon(NULL, IDI_QUESTION);
    r = SendMessage(hWndStatus, SB_SETICON, 1, 0);
    ok(r != 0 ||
       broken(r == 0), /* win95 */
       "Expected non-zero, got %d\n", r);
    r = SendMessage(hWndStatus, SB_SETICON, 1, (LPARAM) hIcon);
    ok(r != 0 ||
       broken(r == 0), /* win95 */
       "Expected non-zero, got %d\n", r);
    r = SendMessage(hWndStatus, SB_SETICON, 1, 0);
    ok(r != 0 ||
       broken(r == 0), /* win95 */
       "Expected non-zero, got %d\n", r);

    /* Set the Unicode format */
    r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, FALSE, 0);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_GETUNICODEFORMAT, 0, 0);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, TRUE, 0);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_GETUNICODEFORMAT, 0, 0);
    ok(r == TRUE ||
       broken(r == FALSE), /* win95 */
       "Expected TRUE, got %d\n", r);

    /* Reset number of parts */
    r = SendMessage(hWndStatus, SB_SETPARTS, 2, (LPARAM)nParts);
    expect(TRUE,r);
    r = SendMessage(hWndStatus, SB_GETPARTS, 0, 0);
    ok(r == 2, "Expected 2, got %d\n", r);
    r = SendMessage(hWndStatus, SB_SETPARTS, 0, 0);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_GETPARTS, 0, 0);
    ok(r == 2, "Expected 2, got %d\n", r);

    /* Set the minimum height and get rectangle information again */
    SendMessage(hWndStatus, SB_SETMINHEIGHT, 50, 0);
    r = SendMessage(hWndStatus, WM_SIZE, 0, 0);
    expect(0,r);
    r = SendMessage(hWndStatus, SB_GETRECT, 0, (LPARAM)&rc);
    expect(TRUE,r);
    expect(2,rc.top);
    /* The rc.bottom test is system dependent
    expect(22,rc.bottom); */
    expect(0,rc.left);
    expect(50,rc.right);
    r = SendMessage(hWndStatus, SB_GETRECT, -1, (LPARAM)&rc);
    expect(FALSE,r);
    r = SendMessage(hWndStatus, SB_GETRECT, 3, (LPARAM)&rc);
    expect(FALSE,r);

    /* Set the ToolTip text */
    SendMessage(hWndStatus, SB_SETTIPTEXT, 0,(LPARAM) "Tooltip Text");
    lstrcpyA(charArray, "apple");
    SendMessage(hWndStatus, SB_GETTIPTEXT, MAKEWPARAM (0, 20),(LPARAM) charArray);
    ok(strcmp(charArray,"Tooltip Text") == 0 ||
        broken(!strcmp(charArray, "apple")), /* win95 */
        "Expected Tooltip Text, got %s\n", charArray);

    /* Make simple */
    SendMessage(hWndStatus, SB_SIMPLE, TRUE, 0);
    r = SendMessage(hWndStatus, SB_ISSIMPLE, 0, 0);
    ok(r == TRUE ||
       broken(r == FALSE), /* win95 */
       "Expected TRUE, got %d\n", r);

    DestroyWindow(hWndStatus);
}

static LRESULT WINAPI ownerdraw_test_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret;
    if (msg == WM_DRAWITEM)
        g_wmdrawitm_ctr++;
    ret = CallWindowProc(g_wndproc_saved, hwnd, msg, wParam, lParam);
    return ret;
}

static void test_status_ownerdraw(void)
{
    HWND hWndStatus;
    int r;
    const char* statustext = "STATUS TEXT";
    LONG oldstyle;

    /* subclass the main window and make sure it is visible */
    g_wndproc_saved = (WNDPROC) SetWindowLongPtr( g_hMainWnd, GWLP_WNDPROC,
                                                  (LONG_PTR)ownerdraw_test_wndproc );
    ok( g_wndproc_saved != 0, "failed to set the WndProc\n");
    SetWindowPos( g_hMainWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
    oldstyle = GetWindowLong( g_hMainWnd, GWL_STYLE);
    SetWindowLong( g_hMainWnd, GWL_STYLE, oldstyle | WS_VISIBLE);
    /* create a status child window */
    ok((hWndStatus = CreateWindowA(SUBCLASS_NAME, "", WS_CHILD|WS_VISIBLE, 0, 0, 100, 100,
                    g_hMainWnd, NULL, NULL, 0)) != NULL, "CreateWindowA failed\n");
    /* set text */
    g_wmdrawitm_ctr = 0;
    r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)statustext);
    ok( r == TRUE, "Sendmessage returned %d, expected 1\n", r);
    ok( 0 == g_wmdrawitm_ctr, "got %d drawitem messages expected none\n", g_wmdrawitm_ctr);
    /* set same text, with ownerdraw flag */
    g_wmdrawitm_ctr = 0;
    r = SendMessage(hWndStatus, SB_SETTEXT, SBT_OWNERDRAW, (LPARAM)statustext);
    ok( r == TRUE, "Sendmessage returned %d, expected 1\n", r);
    ok( 1 == g_wmdrawitm_ctr, "got %d drawitem messages expected 1\n", g_wmdrawitm_ctr);
    /* ;and again */
    g_wmdrawitm_ctr = 0;
    r = SendMessage(hWndStatus, SB_SETTEXT, SBT_OWNERDRAW, (LPARAM)statustext);
    ok( r == TRUE, "Sendmessage returned %d, expected 1\n", r);
    ok( 1 == g_wmdrawitm_ctr, "got %d drawitem messages expected 1\n", g_wmdrawitm_ctr);
    /* clean up */
    DestroyWindow(hWndStatus);
    SetWindowLong( g_hMainWnd, GWL_STYLE, oldstyle);
    SetWindowLongPtr( g_hMainWnd, GWLP_WNDPROC, (LONG_PTR)g_wndproc_saved );
}

static void test_gettext(void)
{
    HWND hwndStatus = CreateWindow(SUBCLASS_NAME, NULL, WS_CHILD|WS_VISIBLE,
        0, 0, 300, 20, g_hMainWnd, NULL, NULL, NULL);
    char buf[5];
    int r;

    r = SendMessage(hwndStatus, SB_SETTEXT, 0, (LPARAM)"Text");
    expect(TRUE, r);
    r = SendMessage(hwndStatus, WM_GETTEXTLENGTH, 0, 0);
    expect(4, r);
    /* A size of 0 returns the length of the text */
    r = SendMessage(hwndStatus, WM_GETTEXT, 0, 0);
    expect(4, r);
    /* A size of 1 only stores the NULL terminator */
    buf[0] = 0xa;
    r = SendMessage(hwndStatus, WM_GETTEXT, 1, (LPARAM)buf);
    ok( r == 0 || broken(r == 4), "Expected 0 got %d\n", r );
    if (!r) ok(!buf[0], "expected empty buffer\n");
    /* A size of 2 returns a length 1 */
    r = SendMessage(hwndStatus, WM_GETTEXT, 2, (LPARAM)buf);
    ok( r == 1 || broken(r == 4), "Expected 1 got %d\n", r );
    r = SendMessage(hwndStatus, WM_GETTEXT, sizeof(buf), (LPARAM)buf);
    expect(4, r);
    ok(!strcmp(buf, "Text"), "expected Text, got %s\n", buf);
    DestroyWindow(hwndStatus);
}

/* Notify events to parent */
static BOOL g_got_dblclk;
static BOOL g_got_click;
static BOOL g_got_rdblclk;
static BOOL g_got_rclick;

/* Messages to parent */
static BOOL g_got_contextmenu;

static LRESULT WINAPI test_notify_parent_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
       case WM_NOTIFY:
       {
           NMHDR *hdr = ((LPNMHDR)lParam);
           switch(hdr->code)
           {
               case NM_DBLCLK: g_got_dblclk = TRUE; break;
               case NM_CLICK: g_got_click = TRUE; break;
               case NM_RDBLCLK: g_got_rdblclk = TRUE; break;
               case NM_RCLICK: g_got_rclick = TRUE; break;
           }

           /* Return zero to indicate default processing */
           return 0;
       }

       case WM_CONTEXTMENU: g_got_contextmenu = TRUE; return 0;

       default:
            return( DefWindowProcA(hwnd, msg, wParam, lParam));
   }

   return 0;
}

/* Test that WM_NOTIFY messages from the status control works correctly */
static void test_notify(void)
{
    HWND hwndParent;
    HWND hwndStatus;
    ATOM atom;
    WNDCLASSA wclass = {0};
    wclass.lpszClassName = "TestNotifyParentClass";
    wclass.lpfnWndProc   = test_notify_parent_proc;
    atom = RegisterClassA(&wclass);
    ok(atom, "RegisterClass failed\n");

    /* create parent */
    hwndParent = CreateWindow(wclass.lpszClassName, "parent", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, 300, 20, NULL, NULL, NULL, NULL);
    ok(hwndParent != NULL, "Parent creation failed!\n");

    /* create status bar */
    hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, WS_VISIBLE | WS_CHILD,
      0, 0, 300, 20, hwndParent, NULL, NULL, NULL);
    ok(hwndStatus != NULL, "Status creation failed!\n");

    /* Send various mouse event, and check that we get them */
    g_got_dblclk = FALSE;
    SendMessage(hwndStatus, WM_LBUTTONDBLCLK, 0, 0);
    ok(g_got_dblclk, "WM_LBUTTONDBLCLK was not processed correctly!\n");
    g_got_rdblclk = FALSE;
    SendMessage(hwndStatus, WM_RBUTTONDBLCLK, 0, 0);
    ok(g_got_rdblclk, "WM_RBUTTONDBLCLK was not processed correctly!\n");
    g_got_click = FALSE;
    SendMessage(hwndStatus, WM_LBUTTONUP, 0, 0);
    ok(g_got_click, "WM_LBUTTONUP was not processed correctly!\n");

    /* For R-UP, check that we also get the context menu from the default processing */
    g_got_contextmenu = FALSE;
    g_got_rclick = FALSE;
    SendMessage(hwndStatus, WM_RBUTTONUP, 0, 0);
    ok(g_got_rclick, "WM_RBUTTONUP was not processed correctly!\n");
    ok(g_got_contextmenu, "WM_RBUTTONUP did not activate the context menu!\n");
}

START_TEST(status)
{
    hinst = GetModuleHandleA(NULL);

    g_hMainWnd = CreateWindowExA(0, "static", "", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
      226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
      NULL, NULL, GetModuleHandleA(NULL), 0);

    InitCommonControls();

    register_subclass();

    test_status_control();
    test_create();
    test_height();
    test_status_ownerdraw();
    test_gettext();
    test_notify();
}
