/********************************************************************** * ExtEscape (X11DRV.@) */ static INT X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data, INT out_count, LPVOID out_data ) { X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); switch(escape) { case QUERYESCSUPPORT: if (in_data && in_count >= sizeof(DWORD)) { switch (*(const INT *)in_data) { case X11DRV_ESCAPE: return TRUE; } } break; case X11DRV_ESCAPE: if (in_data && in_count >= sizeof(enum x11drv_escape_codes)) { switch(*(const enum x11drv_escape_codes *)in_data) { case X11DRV_SET_DRAWABLE: if (in_count >= sizeof(struct x11drv_escape_set_drawable)) { const struct x11drv_escape_set_drawable *data = in_data; physDev->dc_rect = data->dc_rect; physDev->drawable = data->drawable; XFreeGC( gdi_display, physDev->gc ); physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL ); XSetGraphicsExposures( gdi_display, physDev->gc, False ); XSetSubwindowMode( gdi_display, physDev->gc, data->mode ); TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n", dev->hdc, physDev->drawable, wine_dbgstr_rect(&physDev->dc_rect) ); return TRUE; } break; case X11DRV_GET_DRAWABLE: if (out_count >= sizeof(struct x11drv_escape_get_drawable)) { struct x11drv_escape_get_drawable *data = out_data; data->drawable = physDev->drawable; return TRUE; } break; case X11DRV_FLUSH_GL_DRAWABLE: if (in_count >= sizeof(struct x11drv_escape_flush_gl_drawable)) { const struct x11drv_escape_flush_gl_drawable *data = in_data; RECT rect = physDev->dc_rect; OffsetRect( &rect, -physDev->dc_rect.left, -physDev->dc_rect.top ); /* The GL drawable may be lagged behind if we don't flush first, so * flush the display make sure we copy up-to-date data */ XFlush( gdi_display ); XSetFunction( gdi_display, physDev->gc, GXcopy ); XCopyArea( gdi_display, data->gl_drawable, physDev->drawable, physDev->gc, 0, 0, rect.right, rect.bottom, physDev->dc_rect.left, physDev->dc_rect.top ); add_device_bounds( physDev, &rect ); return TRUE; } break; case X11DRV_START_EXPOSURES: XSetGraphicsExposures( gdi_display, physDev->gc, True ); physDev->exposures = 0; return TRUE; case X11DRV_END_EXPOSURES: if (out_count >= sizeof(HRGN)) { HRGN hrgn = 0, tmp = 0; XSetGraphicsExposures( gdi_display, physDev->gc, False ); if (physDev->exposures) { for (;;) { XEvent event; XWindowEvent( gdi_display, physDev->drawable, ~0, &event ); if (event.type == NoExpose) break; if (event.type == GraphicsExpose) { RECT rect; rect.left = event.xgraphicsexpose.x - physDev->dc_rect.left; rect.top = event.xgraphicsexpose.y - physDev->dc_rect.top; rect.right = rect.left + event.xgraphicsexpose.width; rect.bottom = rect.top + event.xgraphicsexpose.height; if (GetLayout( dev->hdc ) & LAYOUT_RTL) mirror_rect( &physDev->dc_rect, &rect ); TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect), event.xgraphicsexpose.count ); if (!tmp) tmp = CreateRectRgnIndirect( &rect ); else SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom ); if (hrgn) CombineRgn( hrgn, hrgn, tmp, RGN_OR ); else { hrgn = tmp; tmp = 0; } if (!event.xgraphicsexpose.count) break; } else { ERR( "got unexpected event %d\n", event.type ); break; } } if (tmp) DeleteObject( tmp ); } *(HRGN *)out_data = hrgn; return TRUE; } break; default: break; } } break; } return 0; }
int drawText(const char * pszText, SIZE& tSize, Device::TextAlign eAlign) { int nRet = 0; wchar_t * pwszBuffer = nullptr; wchar_t* fixedText = nullptr; do { CC_BREAK_IF(! pszText); DWORD dwFmt = DT_WORDBREAK; DWORD dwHoriFlag = (int)eAlign & 0x0f; DWORD dwVertFlag = ((int)eAlign & 0xf0) >> 4; switch (dwHoriFlag) { case 1: // left dwFmt |= DT_LEFT; break; case 2: // right dwFmt |= DT_RIGHT; break; case 3: // center dwFmt |= DT_CENTER; break; } int nLen = strlen(pszText); // utf-8 to utf-16 int nBufLen = nLen + 1; pwszBuffer = new wchar_t[nBufLen]; CC_BREAK_IF(! pwszBuffer); memset(pwszBuffer, 0, sizeof(wchar_t)*nBufLen); nLen = MultiByteToWideChar(CP_UTF8, 0, pszText, nLen, pwszBuffer, nBufLen); if (strchr(pszText, '&')) { fixedText = new wchar_t[nLen * 2 + 1]; int fixedIndex = 0; for (int index = 0; index < nLen; ++index) { if (pwszBuffer[index] == '&') { fixedText[fixedIndex] = '&'; fixedText[fixedIndex + 1] = '&'; fixedIndex += 2; } else { fixedText[fixedIndex] = pwszBuffer[index]; fixedIndex += 1; } } fixedText[fixedIndex] = '\0'; nLen = fixedIndex; } SIZE newSize; if (fixedText) { newSize = sizeWithText(fixedText, nLen, dwFmt, tSize.cx); } else { newSize = sizeWithText(pwszBuffer, nLen, dwFmt, tSize.cx); } RECT rcText = {0}; // if content width is 0, use text size as content size if (tSize.cx <= 0) { tSize = newSize; rcText.right = newSize.cx; rcText.bottom = newSize.cy; } else { LONG offsetX = 0; LONG offsetY = 0; rcText.right = newSize.cx; // store the text width to rectangle // calculate text horizontal offset if (1 != dwHoriFlag // and text isn't align to left && newSize.cx < tSize.cx) // and text's width less then content width, { // then need adjust offset of X. offsetX = (2 == dwHoriFlag) ? tSize.cx - newSize.cx // align to right : (tSize.cx - newSize.cx) / 2; // align to center } // if content height is 0, use text height as content height // else if content height less than text height, use content height to draw text if (tSize.cy <= 0) { tSize.cy = newSize.cy; dwFmt |= DT_NOCLIP; rcText.bottom = newSize.cy; // store the text height to rectangle } else if (tSize.cy < newSize.cy) { // content height larger than text height need, clip text to rect rcText.bottom = tSize.cy; } else { rcText.bottom = newSize.cy; // store the text height to rectangle // content larger than text, need adjust vertical position dwFmt |= DT_NOCLIP; // calculate text vertical offset offsetY = (2 == dwVertFlag) ? tSize.cy - newSize.cy // align to bottom : (3 == dwVertFlag) ? (tSize.cy - newSize.cy) / 2 // align to middle : 0; // align to top } if (offsetX || offsetY) { OffsetRect(&rcText, offsetX, offsetY); } } CC_BREAK_IF(! prepareBitmap(tSize.cx, tSize.cy)); // draw text HGDIOBJ hOldFont = SelectObject(_DC, _font); HGDIOBJ hOldBmp = SelectObject(_DC, _bmp); SetBkMode(_DC, TRANSPARENT); SetTextColor(_DC, RGB(255, 255, 255)); // white color // draw text if (fixedText) { nRet = DrawTextW(_DC, fixedText, nLen, &rcText, dwFmt); } else { nRet = DrawTextW(_DC, pwszBuffer, nLen, &rcText, dwFmt); } //DrawTextA(_DC, pszText, nLen, &rcText, dwFmt); SelectObject(_DC, hOldBmp); SelectObject(_DC, hOldFont); } while (0); CC_SAFE_DELETE_ARRAY(pwszBuffer); delete[] fixedText; return nRet; }
static u32 win_proc(MSG *pMsg) { HWND hwnd; HDC hdc; RECT rc,rc0; u32 i,x,y; hwnd =pMsg->hwnd; switch(pMsg->Code) { case MSG_CREATE: cfg_idx =0; bBorder=TRUE; bBKGND=TRUE; bColor=TRUE; for(i=0;i<8;i++) { timer_count[i] =0; timer_run[i] =FALSE; } GetClientRect(hwnd,&rc0); CreateWindow(BUTTON,"关闭",WS_CHILD|BS_NORMAL|WS_BORDER|WS_VISIBLE,RectW(&rc0)-64,RectH(&rc0)-28,60,24,hwnd,ID_CLOSE,NULL); y=20; x=128+8; CreateWindow(BUTTON,"运行",WS_CHILD|BS_HOLD|WS_VISIBLE,x,y+0*28,60,24,hwnd,ID_START_1,NULL); CreateWindow(BUTTON,"运行",WS_CHILD|BS_HOLD|WS_VISIBLE,x,y+1*28,60,24,hwnd,ID_START_2,NULL); CreateWindow(BUTTON,"运行",WS_CHILD|BS_HOLD|WS_VISIBLE,x,y+2*28,60,24,hwnd,ID_START_3,NULL); CreateWindow(BUTTON,"运行",WS_CHILD|BS_HOLD|WS_VISIBLE,x,y+3*28,60,24,hwnd,ID_START_4,NULL); y=20; x=128+8+64; CreateWindow(BUTTON,"清零",WS_CHILD|WS_VISIBLE,x,y+0*28,60,24,hwnd,ID_CLR_1,NULL); CreateWindow(BUTTON,"清零",WS_CHILD|WS_VISIBLE,x,y+1*28,60,24,hwnd,ID_CLR_2,NULL); CreateWindow(BUTTON,"清零",WS_CHILD|WS_VISIBLE,x,y+2*28,60,24,hwnd,ID_CLR_3,NULL); CreateWindow(BUTTON,"清零",WS_CHILD|WS_VISIBLE,x,y+3*28,60,24,hwnd,ID_CLR_4,NULL); GDD_CreateTimer(hwnd,0,timer_interval[0],0); GDD_CreateTimer(hwnd,1,timer_interval[1],0); GDD_CreateTimer(hwnd,2,timer_interval[2],0); GDD_CreateTimer(hwnd,3,timer_interval[3],0); GDD_CreateTimer(hwnd,7,500,TMR_START); break; //// case MSG_TIMER: { i =pMsg->Param1&0xFF; timer_count[i]++; InvalidateWindow(hwnd); } break; case MSG_NOTIFY: { u16 event,id; event =HI16(pMsg->Param1); id =LO16(pMsg->Param1); switch(event) { case BTN_DOWN: //按钮按下 if(id>=ID_START_1 && id<=ID_START_4) { i =id&0xF; timer_run[i] =TRUE; GDD_ResetTimer(GDD_FindTimer(hwnd,i),timer_interval[i],TMR_START); } if(id>=ID_CLR_1 && id<=ID_CLR_4) { i =id&0xF; timer_count[i] =0; InvalidateWindow(hwnd); } break; //// case BTN_UP: //按钮弹起 if(id==ID_CLOSE) { PostMessage(hwnd,MSG_CLOSE,0,0); } if(id>=ID_START_1 && id<=ID_START_4) { i =id&0xF; timer_run[i] =FALSE; GDD_ResetTimer(GDD_FindTimer(hwnd,i),timer_interval[i],0); } break; //// } } break; //// case MSG_PAINT: { char wbuf[32]; hdc =BeginPaint(hwnd); GetClientRect(hwnd,&rc0); SetFillColor(hdc,RGB(100,100,100)); FillRect(hdc,&rc0); SetRect(&rc,4,20,128,24); for(i=0;i<4;i++) { SetTextColor(hdc,DrawText_Color_Tbl[i].text_color); SetDrawColor(hdc,DrawText_Color_Tbl[i].bd_color); SetFillColor(hdc,DrawText_Color_Tbl[i].bk_color); sprintf(wbuf," 定时器%d: %d",i+1,timer_count[i]); if(timer_run[i]!=FALSE) { DrawText(hdc,wbuf,-1,&rc,DT_LEFT|DT_VCENTER|DT_BORDER|DT_BKGND); } else { if(timer_count[7]&0x01) { DrawText(hdc,wbuf,-1,&rc,DT_LEFT|DT_VCENTER|DT_BORDER|DT_BKGND); } else { DrawText(hdc,wbuf,-1,&rc,DT_LEFT|DT_VCENTER|DT_BKGND); } } OffsetRect(&rc,0,28); } EndPaint(hwnd,hdc); } break; //// default: return DefWindowProc(pMsg); } return 0; }
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch ( msg ) { case WM_CREATE: { CreateMenus(); // Set our menu bar. SetMenu( hWnd, g_hMenu ); // Create our listview window. g_hWnd_list = CreateWindow( WC_LISTVIEW, NULL, LVS_REPORT | LVS_EDITLABELS | LVS_OWNERDRAWFIXED | WS_CHILDWINDOW | WS_VISIBLE, 0, 0, MIN_WIDTH, MIN_HEIGHT, hWnd, NULL, NULL, NULL ); SendMessage( g_hWnd_list, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES ); // Make pretty font. SendMessage( g_hWnd_list, WM_SETFONT, ( WPARAM )hFont, 0 ); // Allow drag and drop for the listview. DragAcceptFiles( g_hWnd_list, TRUE ); // Subclass our listview to receive WM_DROPFILES. ListViewProc = ( WNDPROC )GetWindowLong( g_hWnd_list, GWL_WNDPROC ); SetWindowLong( g_hWnd_list, GWL_WNDPROC, ( LONG )ListViewSubProc ); // Initialize our listview columns LVCOLUMNA lvc = { NULL }; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; lvc.fmt = LVCFMT_CENTER; lvc.pszText = "#"; lvc.cx = 34; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 0, ( LPARAM )&lvc ); lvc.fmt = LVCFMT_LEFT; lvc.pszText = "Filename"; lvc.cx = 135; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 1, ( LPARAM )&lvc ); lvc.fmt = LVCFMT_RIGHT; lvc.pszText = "Cache Entry Offset"; lvc.cx = 110; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 2, ( LPARAM )&lvc ); lvc.pszText = "Cache Entry Size"; lvc.cx = 95; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 3, ( LPARAM )&lvc ); lvc.pszText = "Data Offset"; lvc.cx = 88; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 4, ( LPARAM )&lvc ); lvc.pszText = "Data Size"; lvc.cx = 65; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 5, ( LPARAM )&lvc ); lvc.fmt = LVCFMT_LEFT; lvc.pszText = "Data Checksum"; lvc.cx = 125; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 6, ( LPARAM )&lvc ); lvc.pszText = "Header Checksum"; lvc.cx = 125; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 7, ( LPARAM )&lvc ); lvc.pszText = "Cache Entry Hash"; lvc.cx = 125; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 8, ( LPARAM )&lvc ); lvc.pszText = "System"; lvc.cx = 85; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 9, ( LPARAM )&lvc ); lvc.pszText = "Location"; lvc.cx = 200; SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 10, ( LPARAM )&lvc ); // Save our initial window position. GetWindowRect( hWnd, &last_pos ); return 0; } break; case WM_KEYDOWN: { // We'll just give the listview control focus since it's handling our keypress events. SetFocus( g_hWnd_list ); return 0; } break; case WM_MOVING: { POINT cur_pos; RECT wa; RECT *rc = ( RECT * )lParam; GetCursorPos( &cur_pos ); OffsetRect( rc, cur_pos.x - ( rc->left + cx ), cur_pos.y - ( rc->top + cy ) ); // Allow our main window to attach to the desktop edge. SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 ); if( is_close( rc->left, wa.left ) ) // Attach to left side of the desktop. { OffsetRect( rc, wa.left - rc->left, 0 ); } else if ( is_close( wa.right, rc->right ) ) // Attach to right side of the desktop. { OffsetRect( rc, wa.right - rc->right, 0 ); } if( is_close( rc->top, wa.top ) ) // Attach to top of the desktop. { OffsetRect( rc, 0, wa.top - rc->top ); } else if ( is_close( wa.bottom, rc->bottom ) ) // Attach to bottom of the desktop. { OffsetRect( rc, 0, wa.bottom - rc->bottom ); } // Allow our main window to attach to the image window. GetWindowRect( g_hWnd_image, &wa ); if ( is_attached == false && IsWindowVisible( g_hWnd_image ) ) { if( is_close( rc->right, wa.left ) ) // Attach to left side of image window. { // Allow it to snap only to the dimensions of the image window. if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) ) { OffsetRect( rc, wa.left - rc->right, 0 ); is_attached = true; } } else if ( is_close( wa.right, rc->left ) ) // Attach to right side of image window. { // Allow it to snap only to the dimensions of the image window. if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) ) { OffsetRect( rc, wa.right - rc->left, 0 ); is_attached = true; } } if( is_close( rc->bottom, wa.top ) ) // Attach to top of image window. { // Allow it to snap only to the dimensions of the image window. if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) ) { OffsetRect( rc, 0, wa.top - rc->bottom ); is_attached = true; } } else if ( is_close( wa.bottom, rc->top ) ) // Attach to bottom of image window. { // Allow it to snap only to the dimensions of the image window. if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) ) { OffsetRect( rc, 0, wa.bottom - rc->top ); is_attached = true; } } } // See if our image window is visible if ( IsWindowVisible( g_hWnd_image ) ) { // If it's attached, then move it in proportion to our main window. if ( is_attached == true ) { // If our main window attached itself to the image window, then we'll skip moving the image window. if ( skip_main == true ) { // Moves the image window with the main window. MoveWindow( g_hWnd_image, wa.left + ( rc->left - last_pos.left ), wa.top + ( rc->top - last_pos.top ), wa.right - wa.left, wa.bottom - wa.top, FALSE ); } else { // This causes the image window to snap to the main window. Kinda like a magnet. This is how they work by the way. MoveWindow( hWnd, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, FALSE ); } skip_main = true; } } // Save our last position. last_pos.bottom = rc->bottom; last_pos.left = rc->left; last_pos.right = rc->right; last_pos.top = rc->top; return TRUE; } break; case WM_ENTERSIZEMOVE: { //Get the current position of our window before it gets moved. POINT cur_pos; RECT rc; GetWindowRect( hWnd, &rc ); GetCursorPos( &cur_pos ); cx = cur_pos.x - rc.left; cy = cur_pos.y - rc.top; return 0; } break; case WM_SIZE: { // If our window changes size, assume we aren't attached anymore. is_attached = false; skip_main = false; RECT rc; GetClientRect( hWnd, &rc ); // Allow our listview to resize in proportion to the main window. HDWP hdwp = BeginDeferWindowPos( 1 ); DeferWindowPos( hdwp, g_hWnd_list, HWND_TOP, 0, 0, rc.right, rc.bottom, 0 ); EndDeferWindowPos( hdwp ); return 0; } break; case WM_MEASUREITEM: { // Set the row height of the list view. if ( ( ( LPMEASUREITEMSTRUCT )lParam )->CtlType = ODT_LISTVIEW ) { ( ( LPMEASUREITEMSTRUCT )lParam )->itemHeight = row_height; } return TRUE; } break; case WM_GETMINMAXINFO: { // Set the minimum dimensions that the window can be sized to. ( ( MINMAXINFO * )lParam )->ptMinTrackSize.x = MIN_WIDTH; ( ( MINMAXINFO * )lParam )->ptMinTrackSize.y = MIN_HEIGHT; return 0; } break; case WM_CHANGE_CURSOR: { // SetCursor must be called from the window thread. if ( wParam == TRUE ) { wait_cursor = LoadCursor( NULL, IDC_APPSTARTING ); // Arrow + hourglass. SetCursor( wait_cursor ); } else { SetCursor( LoadCursor( NULL, IDC_ARROW ) ); // Default arrow. wait_cursor = NULL; } } break; case WM_SETCURSOR: { if ( wait_cursor != NULL ) { SetCursor( wait_cursor ); // Keep setting our cursor if it reverts back to the default. return TRUE; } DefWindowProc( hWnd, msg, wParam, lParam ); return FALSE; } break; case WM_COMMAND: { // Check to see if our command is a menu item. if ( HIWORD( wParam ) == 0 ) { // Get the id of the menu item. switch( LOWORD( wParam ) ) { case MENU_OPEN: { pathinfo *pi = ( pathinfo * )malloc( sizeof( pathinfo ) ); pi->filepath = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH * MAX_PATH ); wmemset( pi->filepath, 0, MAX_PATH * MAX_PATH ); OPENFILENAME ofn = { NULL }; ofn.lStructSize = sizeof( OPENFILENAME ); ofn.lpstrFilter = L"Thumbcache Database Files (*.db)\0*.db\0Iconcache Database Files (*.db)\0*.db\0All Files (*.*)\0*.*\0"; ofn.lpstrFile = pi->filepath; ofn.nMaxFile = MAX_PATH * MAX_PATH; ofn.lpstrTitle = L"Open a Thumbcache Database file"; ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_READONLY; ofn.hwndOwner = hWnd; // Display the Open File dialog box if ( GetOpenFileName( &ofn ) ) { pi->offset = ofn.nFileOffset; pi->output_path = NULL; pi->type = 0; cmd_line = 0; // pi will be freed in the thread. CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &read_thumbcache, ( void * )pi, 0, NULL ) ); } else { free( pi->filepath ); free( pi ); } } break; case MENU_SAVE_ALL: case MENU_SAVE_SEL: { // Open a browse for folder dialog box. BROWSEINFO bi = { 0 }; bi.hwndOwner = hWnd; if ( LOWORD( wParam ) == MENU_SAVE_ALL ) { bi.lpszTitle = L"Select a location to save all the file(s)."; } else { bi.lpszTitle = L"Select a location to save the selected file(s)."; } bi.ulFlags = BIF_EDITBOX | BIF_VALIDATE; LPITEMIDLIST lpiidl = SHBrowseForFolder( &bi ); if ( lpiidl ) { wchar_t *save_directory = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH ); wmemset( save_directory, 0, MAX_PATH ); // Get the directory path from the id list. SHGetPathFromIDList( lpiidl, save_directory ); CoTaskMemFree( lpiidl ); save_param *save_type = ( save_param * )malloc( sizeof( save_param ) ); // Freed in the save_items thread. save_type->type = 0; // Save files to filepath. The directory should exist so no need to build it. save_type->save_all = ( LOWORD( wParam ) == MENU_SAVE_ALL ? true : false ); save_type->filepath = save_directory; CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_items, ( void * )save_type, 0, NULL ) ); } } break; case MENU_EXPORT: { wchar_t *file_path = ( wchar_t * )malloc( sizeof ( wchar_t ) * MAX_PATH ); wmemset( file_path, 0, MAX_PATH ); OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof( OPENFILENAME ); ofn.hwndOwner = hWnd; ofn.lpstrFilter = L"CSV (Comma delimited) (*.csv)\0*.csv\0"; ofn.lpstrDefExt = L"csv"; ofn.lpstrTitle = L"Export list to a CSV (comma-separated values) file"; ofn.lpstrFile = file_path; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_READONLY; if ( GetSaveFileName( &ofn ) ) { // file_path is freed in the save_csv thread. CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_csv, ( void * )file_path, 0, NULL ) ); } else { free( file_path ); } } break; case MENU_HIDE_BLANK: { hide_blank_entries = !hide_blank_entries; // Put a check next to the menu item if we choose to hide blank entries. Remove it if we don't. CheckMenuItem( g_hMenu, MENU_HIDE_BLANK, ( hide_blank_entries ? MF_CHECKED : MF_UNCHECKED ) ); // Hide if we have items in the list and show if we have blank entries. if ( ( g_be == NULL && SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) || g_be != NULL ) { CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &show_hide_items, ( void * )NULL, 0, NULL ) ); } } break; case MENU_CHECKSUMS: { // Go through each item in the list and verify the header and data checksums. CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &verify_checksums, ( void * )NULL, 0, NULL ) ); } break; case MENU_SCAN: { SendMessage( g_hWnd_scan, WM_PROPAGATE, 0, 0 ); } break; case MENU_REMOVE_SEL: { // Hide the image window since the selected item will be deleted. if ( IsWindowVisible( g_hWnd_image ) ) { ShowWindow( g_hWnd_image, SW_HIDE ); } is_attached = false; skip_main = false; CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &remove_items, ( void * )NULL, 0, NULL ) ); } break; case MENU_COPY_SEL: { CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, ©_items, ( void * )0, 0, NULL ) ); } break; case MENU_SELECT_ALL: { // Set the state of all items to selected. LVITEM lvi = { NULL }; lvi.mask = LVIF_STATE; lvi.state = LVIS_SELECTED; lvi.stateMask = LVIS_SELECTED; SendMessage( g_hWnd_list, LVM_SETITEMSTATE, -1, ( LPARAM )&lvi ); UpdateMenus( UM_ENABLE ); } break; case MENU_INFO: { LVITEM lvi = { NULL }; lvi.mask = LVIF_PARAM; lvi.iItem = SendMessage( g_hWnd_list, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED ); if ( lvi.iItem != -1 ) { SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi ); SendMessage( g_hWnd_info, WM_PROPAGATE, 0, lvi.lParam ); } } break; case MENU_ABOUT: { MessageBoxA( hWnd, "Thumbcache Viewer is made free under the GPLv3 license.\r\n\r\nVersion 1.0.3.1\r\n\r\nCopyright \xA9 2011-2015 Eric Kutcher", PROGRAM_CAPTION_A, MB_APPLMODAL | MB_ICONINFORMATION ); } break; case MENU_EXIT: { SendMessage( hWnd, WM_CLOSE, 0, 0 ); } break; } } return 0; } break; case WM_NOTIFY: { // Get our listview codes. switch ( ( ( LPNMHDR )lParam )->code ) { case LVN_KEYDOWN: { NMLVKEYDOWN *nmlvkd = ( NMLVKEYDOWN * )lParam; // Make sure the control key is down and that we're not already in a worker thread. Prevents threads from queuing in case the user falls asleep on their keyboard. if ( GetKeyState( VK_CONTROL ) & 0x8000 && in_thread == false ) { // Determine which key was pressed. switch ( nmlvkd->wVKey ) { case 'A': // Select all items if Ctrl + A is down and there are items in the list. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_SELECT_ALL, 0 ); } } break; case 'O': // Open the file dialog box if Ctrl + O is down. { SendMessage( hWnd, WM_COMMAND, MENU_OPEN, 0 ); } break; case 'H': // Hide blank entries if Ctrl + H is down. { SendMessage( hWnd, WM_COMMAND, MENU_HIDE_BLANK, 0 ); } break; case 'V': // Verify checksums. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_CHECKSUMS, 0 ); } } break; case 'M': // Map entry hash values to local files. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_SCAN, 0 ); } } break; case 'R': // Remove selected items if Ctrl + R is down and there are selected items in the list. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_REMOVE_SEL, 0 ); } } break; case 'C': // Copy selected items if Ctrl + C is down and there are selected items in the list. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_COPY_SEL, 0 ); } } break; case 'S': // Save all/selected items if Ctrl + S or Ctrl + Shift + S is down and there are items in the list. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 && !( GetKeyState( VK_SHIFT ) & 0x8000 ) ) // Shift not down. { SendMessage( hWnd, WM_COMMAND, MENU_SAVE_ALL, 0 ); } else if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 && ( GetKeyState( VK_SHIFT ) & 0x8000 ) ) // Shift down. { SendMessage( hWnd, WM_COMMAND, MENU_SAVE_SEL, 0 ); } } break; case 'I': // View extended information if Ctrl + I is down and there are selected items in the list. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 ); } } break; case 'E': // Export list to a CSV (comma-separated values) file. { if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) { SendMessage( hWnd, WM_COMMAND, MENU_EXPORT, 0 ); } } break; } } } break; case LVN_COLUMNCLICK: { NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam; // Change the format of the items in the column if Ctrl is held while clicking the column. if ( GetKeyState( VK_CONTROL ) & 0x8000 ) { switch ( nmlv->iSubItem ) { case 2: // Change the cache entry offset column info. { is_kbytes_c_offset = !is_kbytes_c_offset; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 3: // Change the cache entry size column info. { is_kbytes_c_size = !is_kbytes_c_size; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 4: // Change the data offset column info. { is_kbytes_d_offset = !is_kbytes_d_offset; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 5: // Change the data size column info. { is_kbytes_d_size = !is_kbytes_d_size; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 6: // Change the data checksum column info. { is_dc_lower = !is_dc_lower; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 7: // Change the header checksum column info. { is_hc_lower = !is_hc_lower; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; case 8: // Change the entry hash column info. { is_eh_lower = !is_eh_lower; InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE ); } break; } } else // Normal column click. Sort the items in the column. { LVCOLUMN lvc = { NULL }; lvc.mask = LVCF_FMT; SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc ); if ( HDF_SORTUP & lvc.fmt ) // Column is sorted upward. { // Sort down lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) | HDF_SORTDOWN; SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, ( WPARAM )nmlv->iSubItem, ( LPARAM )&lvc ); SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc ); } else if ( HDF_SORTDOWN & lvc.fmt ) // Column is sorted downward. { // Sort up lvc.fmt = lvc.fmt & ( ~HDF_SORTDOWN ) | HDF_SORTUP; SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc ); SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem + NUM_COLUMNS, ( LPARAM )( PFNLVCOMPARE )CompareFunc ); } else // Column has no sorting set. { // Remove the sort format for all columns. for ( int i = 0; i < NUM_COLUMNS; i++ ) { // Get the current format SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, i, ( LPARAM )&lvc ); // Remove sort up and sort down lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) & ( ~HDF_SORTDOWN ); SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, i, ( LPARAM )&lvc ); } // Read current the format from the clicked column SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc ); // Sort down to start. lvc.fmt = lvc.fmt | HDF_SORTDOWN; SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc ); SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc ); } } } break; case NM_RCLICK: { // Show our edit context menu as a popup. POINT p; GetCursorPos( &p ) ; TrackPopupMenu( g_hMenuSub_context, 0, p.x, p.y, 0, hWnd, NULL ); } break; case NM_DBLCLK: { NMITEMACTIVATE *nmitem = ( NMITEMACTIVATE *)lParam; if ( nmitem->iItem != -1 ) { SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 ); } } break; case LVN_DELETEITEM: { NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam; // Item count will be 1 since the item hasn't yet been deleted. if ( SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) == 1 ) { // Disable the menus that require at least one item in the list. UpdateMenus( UM_DISABLE_OVERRIDE ); } } break; case LVN_ITEMCHANGED: { NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam; if ( in_thread == false ) { UpdateMenus( UM_ENABLE ); } // Only load images that are selected and in focus. if ( nmlv->uNewState != ( LVIS_FOCUSED | LVIS_SELECTED ) ) { break; } // Retrieve the lParam value from the selected listview item. LVITEM lvi = { NULL }; lvi.mask = LVIF_PARAM; lvi.iItem = nmlv->iItem; SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi ); fileinfo *fi = ( fileinfo * )lvi.lParam; if ( fi == NULL || ( fi != NULL && fi->si == NULL ) ) { break; } // Create a buffer to read in our new bitmap. char *current_image = ( char * )malloc( sizeof( char ) * fi->size ); // Attempt to open a file for reading. HANDLE hFile = CreateFile( fi->si->dbpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile != INVALID_HANDLE_VALUE ) { DWORD read = 0; // Set our file pointer to the beginning of the database file. SetFilePointer( hFile, fi->data_offset, 0, FILE_BEGIN ); // Read the entire image into memory. ReadFile( hFile, current_image, fi->size, &read, NULL ); CloseHandle( hFile ); // If gdi_image exists, then delete it. if ( gdi_image != NULL ) { delete gdi_image; gdi_image = NULL; } // Create a stream to store our buffer and then store the stream into a GDI+ image object. ULONG written = 0; IStream *is = NULL; CreateStreamOnHGlobal( NULL, TRUE, &is ); is->Write( current_image, read, &written ); // Only write what we've read. gdi_image = new Gdiplus::Image( is ); is->Release(); if ( !IsWindowVisible( g_hWnd_image ) ) { // Move our image window next to the main window on its right side if it's the first time we're showing the image window. if ( first_show == false ) { SetWindowPos( g_hWnd_image, HWND_TOPMOST, last_pos.right, last_pos.top, MIN_HEIGHT, MIN_HEIGHT, SWP_NOACTIVATE ); first_show = true; } // This is done to keep both windows on top of other windows. // Set the image window position on top of all windows except topmost windows, but don't set focus to it. SetWindowPos( g_hWnd_image, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE ); // Set our main window on top of the image window. SetWindowPos( hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); // The image window is on top of everything (except the main window), set it back to non-topmost. SetWindowPos( g_hWnd_image, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW ); } // Set our image window's icon to match the file extension. if ( fi->flag & FIF_TYPE_BMP ) { SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_bmp ); } else if ( fi->flag & FIF_TYPE_JPG ) { SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_jpg ); } else if ( fi->flag & FIF_TYPE_PNG ) { SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_png ); } else { SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, NULL ); } // Set the image window's new title. wchar_t new_title[ MAX_PATH + 30 ] = { 0 }; swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", ( fi->filename != NULL ? fi->filename : L"" ), gdi_image->GetWidth(), gdi_image->GetHeight() ); SetWindowText( g_hWnd_image, new_title ); // See if our image window is minimized and set the rectangle to its old size if it is. RECT rc; if ( IsIconic( g_hWnd_image ) == TRUE ) { rc = last_dim; } else // Otherwise, get the current size. { GetClientRect( g_hWnd_image, &rc ); } old_pos.x = old_pos.y = 0; drag_rect.x = drag_rect.y = 0; // Center the image. drag_rect.x = ( ( long )gdi_image->GetWidth() - rc.right ) / 2; drag_rect.y = ( ( long )gdi_image->GetHeight() - rc.bottom ) / 2; scale = 1.0f; // Reset the image scale. // Force our window to repaint itself. InvalidateRect( g_hWnd_image, NULL, TRUE ); } // Free our image buffer. free( current_image ); } break; case LVN_BEGINLABELEDIT: { NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam; // If no item is being edited, then cancel the edit. if ( pdi->item.iItem == -1 ) { return TRUE; } // Get the current list item text from its lParam. LVITEM lvi = { NULL }; lvi.iItem = pdi->item.iItem; lvi.iSubItem = 1; lvi.mask = LVIF_PARAM; SendMessage( pdi->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi ); // Save our current fileinfo. current_fileinfo = ( fileinfo * )lvi.lParam; if ( current_fileinfo == NULL ) { return TRUE; } // Get the bounding box of the Filename column we're editing. current_edit_pos.top = 1; current_edit_pos.left = LVIR_BOUNDS; SendMessage( pdi->hdr.hwndFrom, LVM_GETSUBITEMRECT, pdi->item.iItem, ( LPARAM )¤t_edit_pos ); // Get the edit control that the listview creates. g_hWnd_edit = ( HWND )SendMessage( pdi->hdr.hwndFrom, LVM_GETEDITCONTROL, 0, 0 ); // Subclass our edit window to modify its position. EditProc = ( WNDPROC )GetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC ); SetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC, ( LONG )EditSubProc ); // Set our edit control's text to the list item's text. SetWindowText( g_hWnd_edit, current_fileinfo->filename ); // Get the length of the filename without the extension. int ext_len = wcslen( current_fileinfo->filename ); while ( ext_len != 0 && current_fileinfo->filename[ --ext_len ] != L'.' ); // Select all the text except the file extension (if ext_len = 0, then everything is selected) SendMessage( g_hWnd_edit, EM_SETSEL, 0, ext_len ); // Allow the edit to proceed. return FALSE; } break; case LVN_ENDLABELEDIT: { NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam; // Prevent the edit if there's no text. if ( pdi->item.pszText == NULL ) { return FALSE; } // Prevent the edit if the text length is 0. unsigned int length = wcslen( pdi->item.pszText ); if ( length == 0 ) { return FALSE; } // Free the old filename. free( current_fileinfo->filename ); // Create a new filename based on the editbox's text. wchar_t *filename = ( wchar_t * )malloc( sizeof( wchar_t ) * ( length + 1 ) ); wmemset( filename, 0, length + 1 ); wcscpy_s( filename, length + 1, pdi->item.pszText ); // Modify our listview item's fileinfo lParam value. current_fileinfo->filename = filename; // Set the image window's new title. wchar_t new_title[ MAX_PATH + 30 ] = { 0 }; swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", filename, gdi_image->GetWidth(), gdi_image->GetHeight() ); SetWindowText( g_hWnd_image, new_title ); return TRUE; } break; } return FALSE; } break; case WM_DRAWITEM: { DRAWITEMSTRUCT *dis = ( DRAWITEMSTRUCT * )lParam; // The item we want to draw is our listview. if ( dis->CtlType == ODT_LISTVIEW && dis->itemData != NULL ) { fileinfo *fi = ( fileinfo * )dis->itemData; if ( fi->si == NULL ) { return TRUE; } // Alternate item color's background. if ( dis->itemID % 2 ) // Even rows will have a light grey background. { HBRUSH color = CreateSolidBrush( ( COLORREF )RGB( 0xF7, 0xF7, 0xF7 ) ); FillRect( dis->hDC, &dis->rcItem, color ); DeleteObject( color ); } // Set the selected item's color. bool selected = false; if ( dis->itemState & ( ODS_FOCUS || ODS_SELECTED ) ) { if ( skip_draw == true ) { return TRUE; // Don't draw selected items because their lParam values are being deleted. } HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) ); FillRect( dis->hDC, &dis->rcItem, color ); DeleteObject( color ); selected = true; } wchar_t tbuf[ MAX_PATH ]; wchar_t *buf = tbuf; // This is the full size of the row. RECT last_rc; // This will keep track of the current colunn's left position. int last_left = 0; // Adjust the alignment position of the text. int RIGHT_COLUMNS = 0; LVCOLUMN lvc = { 0 }; lvc.mask = LVCF_WIDTH; // Loop through all the columns for ( int i = 0; i < NUM_COLUMNS; ++i ) { RIGHT_COLUMNS = 0; // Save the appropriate text in our buffer for the current column. switch ( i ) { case 0: { swprintf_s( buf, MAX_PATH, L"%d", dis->itemID + 1 ); } break; case 1: { buf = ( fi->filename != NULL ? fi->filename : L"" ); } break; case 2: { buf = tbuf; // Reset the buffer pointer. RIGHT_COLUMNS = DT_RIGHT; // Depending on our toggle, output the offset (db location) in either kilobytes or bytes. swprintf_s( buf, MAX_PATH, ( is_kbytes_c_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_c_offset == true ? fi->header_offset : fi->header_offset / 1024 ) ); } break; case 3: { RIGHT_COLUMNS = DT_RIGHT; unsigned int cache_entry_size = fi->size + ( fi->data_offset - fi->header_offset ); // Depending on our toggle, output the size in either kilobytes or bytes. swprintf_s( buf, MAX_PATH, ( is_kbytes_c_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_c_size == true ? cache_entry_size / 1024 : cache_entry_size ) ); } break; case 4: { RIGHT_COLUMNS = DT_RIGHT; // Depending on our toggle, output the offset (db location) in either kilobytes or bytes. swprintf_s( buf, MAX_PATH, ( is_kbytes_d_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_d_offset == true ? fi->data_offset : fi->data_offset / 1024 ) ); } break; case 5: { RIGHT_COLUMNS = DT_RIGHT; // Depending on our toggle, output the size in either kilobytes or bytes. swprintf_s( buf, MAX_PATH, ( is_kbytes_d_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_d_size == true ? fi->size / 1024 : fi->size ) ); } break; case 6: { // Output the hex string in either lowercase or uppercase. int out = swprintf_s( buf, MAX_PATH, ( is_dc_lower == true ? L"%016llx" : L"%016llX" ), fi->data_checksum ); if ( fi->v_data_checksum != fi->data_checksum ) { swprintf_s( buf + out, MAX_PATH - out, ( is_dc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_data_checksum ); } } break; case 7: { // Output the hex string in either lowercase or uppercase. int out = swprintf_s( buf, MAX_PATH, ( is_hc_lower == true ? L"%016llx" : L"%016llX" ), fi->header_checksum ); if ( fi->v_header_checksum != fi->header_checksum ) { swprintf_s( buf + out, MAX_PATH - out, ( is_hc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_header_checksum ); } } break; case 8: { // Output the hex string in either lowercase or uppercase. swprintf_s( buf, MAX_PATH, ( is_eh_lower == true ? L"%016llx" : L"%016llX" ), fi->entry_hash ); } break; case 9: { switch ( fi->si->system ) { case WINDOWS_VISTA: { buf = L"Windows Vista"; } break; case WINDOWS_7: { buf = L"Windows 7"; } break; case WINDOWS_8: case WINDOWS_8v2: case WINDOWS_8v3: { buf = L"Windows 8"; } break; case WINDOWS_8_1: { buf = L"Windows 8.1"; } break; case WINDOWS_10: { buf = L"Windows 10"; } break; default: { buf = L"Unknown"; } break; } } break; case 10: { buf = fi->si->dbpath; } break; } // Get the dimensions of the listview column SendMessage( dis->hwndItem, LVM_GETCOLUMN, i, ( LPARAM )&lvc ); last_rc = dis->rcItem; // This will adjust the text to fit nicely into the rectangle. last_rc.left = 5 + last_left; last_rc.right = lvc.cx + last_left - 5; // Save the last left position of our column. last_left += lvc.cx; // Save the height and width of this region. int width = last_rc.right - last_rc.left; if ( width <= 0 ) { continue; } int height = last_rc.bottom - last_rc.top; // Normal text position. RECT rc; rc.top = 0; rc.left = 0; rc.right = width; rc.bottom = height; // Shadow text position. //RECT rc2 = rc; //rc2.left += 1; //rc2.top += 1; //rc2.right += 1; //rc2.bottom += 1; // Create and save a bitmap in memory to paint to. HDC hdcMem = CreateCompatibleDC( dis->hDC ); HBITMAP hbm = CreateCompatibleBitmap( dis->hDC, width, height ); HBITMAP ohbm = ( HBITMAP )SelectObject( hdcMem, hbm ); DeleteObject( ohbm ); DeleteObject( hbm ); HFONT ohf = ( HFONT )SelectObject( hdcMem, hFont ); DeleteObject( ohf ); // Transparent background for text. SetBkMode( hdcMem, TRANSPARENT ); // Draw selected text if ( selected == true ) { // Fill the background. HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) ); FillRect( hdcMem, &rc, color ); DeleteObject( color ); // Shadow color - black. //SetTextColor( hdcMem, RGB( 0x00, 0x00, 0x00 ) ); //DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS ); // White text. SetTextColor( hdcMem, RGB( 0xFF, 0xFF, 0xFF ) ); DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS ); BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCCOPY ); } else // Draw normal text. { // Fill the background. HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_WINDOW ) ); FillRect( hdcMem, &rc, color ); DeleteObject( color ); // Shadow color - light grey. //SetTextColor( hdcMem, RGB( 0xE0, 0xE0, 0xE0 ) ); //DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS ); // Show red text if our checksums don't match, green text for entries with extended info, and black text for everything else. COLORREF text_color = RGB( 0x00, 0x00, 0x00 ); if ( i == 1 && fi->ei != NULL ) { text_color = RGB( 0x00, 0x80, 0x00 ); } else if ( ( i == 6 && ( fi->v_data_checksum != fi->data_checksum ) ) || ( i == 7 && ( fi->v_header_checksum != fi->header_checksum ) ) ) { text_color = RGB( 0xFF, 0x00, 0x00 ); } SetTextColor( hdcMem, text_color ); DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS ); BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCAND ); } // Delete our back buffer. DeleteDC( hdcMem ); } } return TRUE; } break; case WM_CLOSE: { // Prevent the possibility of running additional processes. EnableWindow( hWnd, FALSE ); ShowWindow( hWnd, SW_HIDE ); EnableWindow( g_hWnd_image, FALSE ); ShowWindow( g_hWnd_image, SW_HIDE ); EnableWindow( g_hWnd_info, FALSE ); ShowWindow( g_hWnd_info, SW_HIDE ); EnableWindow( g_hWnd_property, FALSE ); ShowWindow( g_hWnd_property, SW_HIDE ); EnableWindow( g_hWnd_scan, FALSE ); ShowWindow( g_hWnd_scan, SW_HIDE ); // If we're in a secondary thread, then kill it (cleanly) and wait for it to exit. if ( in_thread == true ) { CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &cleanup, ( void * )NULL, 0, NULL ) ); } else // Otherwise, destroy the window normally. { g_kill_thread = true; DestroyWindow( hWnd ); } return 0; } break; case WM_DESTROY_ALT: { DestroyWindow( hWnd ); } break; case WM_DESTROY: { // Get the number of items in the listview. int item_count = SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 ); LVITEM lvi = { NULL }; lvi.mask = LVIF_PARAM; fileinfo *fi = NULL; // Go through each item, and free their lParam values. current_fileinfo will get deleted here. for ( int i = 0; i < item_count; ++i ) { lvi.iItem = i; SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi ); fi = ( fileinfo * )lvi.lParam; if ( fi != NULL ) { if ( fi->si != NULL ) { --( fi->si->count ); // Remove our shared information from the linked list if there's no more items for this database. if ( fi->si->count == 0 ) { free( fi->si ); } } cleanup_extended_info( fi->ei ); // First free the filename pointer. free( fi->filename ); // Then free the fileinfo structure. free( fi ); } } // Delete our image object. if ( gdi_image != NULL ) { delete gdi_image; } cleanup_blank_entries(); // Since these aren't owned by a window, we need to destroy them. DestroyMenu( g_hMenuSub_context ); DestroyMenu( g_hMenuSub_ei_context ); PostQuitMessage( 0 ); return 0; } break; default: { return DefWindowProc( hWnd, msg, wParam, lParam ); } break; } return TRUE; }
/* * AmountDialogProc: Dialog procedure for dialog asking user for a number. */ BOOL CALLBACK AmountDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { static AmountDialogStruct *info; static HWND hEdit; DWORD amount; RECT dlg_rect; RECT parent_rect; char buf[MAXAMOUNT + 1]; HWND hwndSpin; switch (message) { case WM_INITDIALOG: hAmountDialog = hDlg; info = (AmountDialogStruct *) lParam; hEdit = GetDlgItem(hDlg, IDC_AMOUNTBOX); GetWindowRect(hDlg, &dlg_rect); GetWindowRect(GetParent(hDlg), &parent_rect); // Position dialog. // Don't let it extend past the edges of the parent. // OffsetRect(&dlg_rect, info->x - dlg_rect.left, info->y - dlg_rect.top); if (dlg_rect.right > parent_rect.right) OffsetRect(&dlg_rect, parent_rect.right - dlg_rect.right, 0); if (dlg_rect.bottom > parent_rect.bottom) OffsetRect(&dlg_rect, 0, parent_rect.bottom - dlg_rect.bottom); if (dlg_rect.left < parent_rect.left) OffsetRect(&dlg_rect, parent_rect.left - dlg_rect.left, 0); if (dlg_rect.top < parent_rect.top) OffsetRect(&dlg_rect, 0, parent_rect.top - dlg_rect.top); MoveWindow(hDlg, dlg_rect.left, dlg_rect.top, dlg_rect.right - dlg_rect.left, dlg_rect.bottom - dlg_rect.top, FALSE); sprintf(buf, "%u", info->amount); Edit_SetText(hEdit, buf); Edit_LimitText(hEdit, MAXAMOUNT); hwndSpin = GetDlgItem(hDlg, IDC_SPIN1); if (info->maxAmount > UD_MAXVAL) SendMessage(hwndSpin,UDM_SETRANGE,0,MAKELONG(UD_MAXVAL,info->minAmount)); else SendMessage(hwndSpin,UDM_SETRANGE,0,MAKELONG(info->maxAmount,info->minAmount)); return TRUE; HANDLE_MSG(hDlg, WM_CTLCOLOREDIT, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORLISTBOX, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORSTATIC, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORDLG, DialogCtlColor); case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: // changed from %d (long) to %u (DWORD) for 'amount' // (1) avoids signed/unsigned mismatch // (2) doesn't need special <= 0 case Edit_GetText(hEdit, buf, MAXAMOUNT); if (sscanf(buf, "%u", &amount) != 1) EndDialog(hDlg, IDCANCEL); else { if (amount < info->minAmount) info->amount = info->minAmount; else if (amount > info->maxAmount) info->amount = info->maxAmount; else info->amount = amount; EndDialog(hDlg, IDOK); } return TRUE; case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; } break; case WM_DESTROY: hAmountDialog = NULL; return TRUE; } return FALSE; }
// which_mode is 0 ... dest is a bitmap // is 1 ... ignore dest ... paint on mainPtr // is 2 ... dest is a dialog, use the dialog pattern // both pattern gworlds are 192 x 256 void paint_pattern(HBITMAP dest,short which_mode,RECT dest_rect,short which_pattern) { HBITMAP source_pat; RECT pattern_source = {32,168,96,232}, pat_dest_orig = {0,0,64,64},pat_dest; short i,j; RECT draw_from_orig = {0,0,192,256},draw_from,draw_to; short store_ulx,store_uly; if (which_mode == 1) OffsetRect(&dest_rect,ulx, uly); else if (which_mode == 3) which_mode = 1; if (which_mode == 2) { source_pat = dialog_pattern_gworld; if (dlog_pat_placed == 0) { dlog_pat_placed = 1; OffsetRect(&pattern_source, 64 * 2,0); for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) { pat_dest = pat_dest_orig; OffsetRect(&pat_dest,64 * i, 64 * j); rect_draw_some_item(mixed_gworld,pattern_source, dialog_pattern_gworld,pat_dest,0,0); } } } else { source_pat = pattern_gworld; if (current_pattern != which_pattern) { current_pattern = which_pattern; OffsetRect(&pattern_source, 64 * (which_pattern % 5), 64 * (which_pattern / 5)); for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) { pat_dest = pat_dest_orig; OffsetRect(&pat_dest,64 * i, 64 * j); rect_draw_some_item(mixed_gworld,pattern_source, pattern_gworld,pat_dest,0,0); } } } // now patterns are loaded, so have fun // first nullify ul shifting store_ulx = ulx; store_uly = uly; ulx = uly = 0; for (i = 0; i < (dest_rect.right / 192) + 1; i++) for (j = 0; j < (dest_rect.bottom / 256) + 1; j++) { draw_to = draw_from_orig; OffsetRect(&draw_to,192 * i, 256 * j); IntersectRect(&draw_to,&draw_to,&dest_rect); if (draw_to.right != 0) { draw_from = draw_to; OffsetRect(&draw_from, -192 * i, -256 * j); switch (which_mode) { case 0: rect_draw_some_item(source_pat,draw_from, dest,draw_to,0,0); break; case 1: rect_draw_some_item(source_pat,draw_from, source_pat,draw_to,0,1); break; case 2: rect_draw_some_item(source_pat,draw_from, dest,draw_to,0,2); break; } } } ulx = store_ulx; uly = store_uly; }
/** * name: PaintThemeButton * desc: Draws the themed button * param: ctl - BTNCTRL structure for the button * hdcMem - device context to draw to * rcClient - rectangle of the whole button * return: nothing **/ static void __fastcall PaintThemeButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) { RECT rcText = { 0, 0, 0, 0 }; WCHAR wszText[MAX_PATH] = { 0 }; WORD ccText; // Draw the flat button if ((ctl->dwStyle & MBS_FLAT) && ctl->hThemeToolbar) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); } DrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), rcClient, rcClient); } else { // draw themed button background if (ctl->hThemeButton) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); } DrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, rcClient, rcClient); } } // calculate text rect { RECT sizeText; HFONT hOldFont; ccText = GetWindowTextW(ctl->hwnd, wszText, _countof(wszText)); if (ccText > 0) { hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); GetThemeTextExtent( ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, wszText, ccText, DST_PREFIXTEXT, NULL, &sizeText); if (ctl->cHot) { RECT rcHot; GetThemeTextExtent(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, L"&", 1, DST_PREFIXTEXT, NULL, &rcHot); sizeText.right -= (rcHot.right - rcHot.left); } SelectObject(hdcMem, hOldFont); rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - (sizeText.right - sizeText.left)) / 2; rcText.top = (rcClient->bottom - rcClient->top - (sizeText.bottom - sizeText.top)) / 2; rcText.right = rcText.left + (sizeText.right - sizeText.left); rcText.bottom = rcText.top + (sizeText.bottom - sizeText.top); if (ctl->stateId == PBS_PRESSED) { OffsetRect(&rcText, 1, 1); } } } PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); // draw text if (ccText > 0 && ctl->hThemeButton) { HFONT hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); DrawThemeText(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, wszText, ccText, DST_PREFIXTEXT, 0, &rcText); SelectObject(hdcMem, hOldFont); } }
// Message handler for about box. INT_PTR CALLBACK DecryptProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: // Get the owner window and dialog box rectangles. HWND hwndOwner; RECT rc, rcDlg, rcOwner; if ((hwndOwner = GetParent(hDlg)) == NULL) { hwndOwner = GetDesktopWindow(); } GetWindowRect(hwndOwner, &rcOwner); GetWindowRect(hDlg, &rcDlg); CopyRect(&rc, &rcOwner); // Offset the owner and dialog box rectangles so that right and bottom // values represent the width and height, and then offset the owner again // to discard space taken up by the dialog box. OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); OffsetRect(&rc, -rc.left, -rc.top); OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); // The new position is the sum of half the remaining space and the owner's // original position. SetWindowPos(hDlg, HWND_TOP, rcOwner.left + (rc.right / 2), rcOwner.top + (rc.bottom / 2), 0, 0, // Ignores size arguments. SWP_NOSIZE); SetWindowText(hDlg, szFile); return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK) { TCHAR pwd[MAX_PASSWORD]; GetDlgItemText(hDlg, IDC_PWD, pwd, MAX_PASSWORD); if (!wcslen(pwd)) { MessageBox(hDlg, L"Password cannot be empty", L"Password error", MB_ICONERROR); break; } if (!SodiumDecryptFile(pwd)) { sodium_memzero(pwd, MAX_PASSWORD); break; } sodium_memzero(pwd, MAX_PASSWORD); EndDialog(hDlg, LOWORD(wParam)); PostQuitMessage(0); return (INT_PTR)TRUE; } else if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); PostQuitMessage(0); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
static void winInitDialog (HWND hwndDlg) { HWND hwndDesk; RECT rc, rcDlg, rcDesk; HICON hIcon, hIconSmall; hwndDesk = GetParent (hwndDlg); if (!hwndDesk || IsIconic (hwndDesk)) hwndDesk = GetDesktopWindow (); /* Remove minimize and maximize buttons */ SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); /* Set Window not to show in the task bar */ SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_APPWINDOW ); /* Center dialog window in the screen. Not done for multi-monitor systems, where * it is likely to end up split across the screens. In that case, it appears * near the Tray icon. */ if (GetSystemMetrics(SM_CMONITORS)>1) { /* Still need to refresh the frame change. */ SetWindowPos (hwndDlg, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); } else { GetWindowRect (hwndDesk, &rcDesk); GetWindowRect (hwndDlg, &rcDlg); CopyRect (&rc, &rcDesk); OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top); OffsetRect (&rc, -rc.left, -rc.top); OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom); SetWindowPos (hwndDlg, HWND_TOPMOST, rcDesk.left + (rc.right / 2), rcDesk.top + (rc.bottom / 2), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED); } #ifdef XWIN_MULTIWINDOW if (g_hIconX) hIcon=g_hIconX; else #endif hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); #ifdef XWIN_MULTIWINDOW if (g_hSmallIconX) hIconSmall=g_hSmallIconX; else #endif hIconSmall = LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); PostMessage (hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon); PostMessage (hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); }
void Draw(HDC aDc) { HDC desktopHdc = NULL; RECT sourceRect, intersectedRect; RECT targetRect, appRect; DWORD rop = SRCCOPY; CURSORINFO cinfo; ICONINFO iinfo; int AppWidth, AppHeight; if (bInvertColors) rop = NOTSRCCOPY; desktopHdc = GetDC(0); GetClientRect(hMainWnd, &appRect); AppWidth = (appRect.right - appRect.left); AppHeight = (appRect.bottom - appRect.top); ZeroMemory(&cinfo, sizeof(cinfo)); ZeroMemory(&iinfo, sizeof(iinfo)); cinfo.cbSize = sizeof(cinfo); GetCursorInfo(&cinfo); GetIconInfo(cinfo.hCursor, &iinfo); targetRect = appRect; ClientToScreen(hMainWnd, (POINT*)&targetRect.left); ClientToScreen(hMainWnd, (POINT*)&targetRect.right); if (bRecreateOffscreenDC || !hdcOffscreen) { bRecreateOffscreenDC = FALSE; if(hdcOffscreen) { SelectObject(hdcOffscreen, hbmpOld); DeleteObject (hbmpOffscreen); DeleteDC(hdcOffscreen); } sourceWidth = AppWidth / iZoom; sourceHeight = AppHeight / iZoom; /* Create a memory DC compatible with client area DC */ hdcOffscreen = CreateCompatibleDC(desktopHdc); /* Create a bitmap compatible with the client area DC */ hbmpOffscreen = CreateCompatibleBitmap( desktopHdc, sourceWidth, sourceHeight); /* Select our bitmap in memory DC and save the old one */ hbmpOld = SelectObject(hdcOffscreen , hbmpOffscreen); } GetWindowRect(hDesktopWindow, &sourceRect); sourceRect.left = (cp.x) - (sourceWidth /2); sourceRect.top = (cp.y) - (sourceHeight /2); sourceRect.right = sourceRect.left + sourceWidth; sourceRect.bottom = sourceRect.top + sourceHeight; GetBestOverlapWithMonitors(&sourceRect); /* Paint the screen bitmap to our in memory DC */ BitBlt( hdcOffscreen, 0, 0, sourceWidth, sourceHeight, desktopHdc, sourceRect.left, sourceRect.top, rop); if (IntersectRect(&intersectedRect, &sourceRect, &targetRect)) { OffsetRect(&intersectedRect, -sourceRect.left, -sourceRect.top); FillRect(hdcOffscreen, &intersectedRect, GetStockObject(DC_BRUSH)); } /* Draw the mouse pointer in the right position */ DrawIcon( hdcOffscreen , pMouse.x - iinfo.xHotspot - sourceRect.left, // - 10, pMouse.y - iinfo.yHotspot - sourceRect.top, // - 10, cinfo.hCursor); /* Blast the stretched image from memory DC to window DC */ StretchBlt( aDc, 0, 0, AppWidth, AppHeight, hdcOffscreen, 0, 0, sourceWidth, sourceHeight, SRCCOPY | NOMIRRORBITMAP); /* Cleanup */ if (iinfo.hbmMask) DeleteObject(iinfo.hbmMask); if (iinfo.hbmColor) DeleteObject(iinfo.hbmColor); ReleaseDC(hDesktopWindow, desktopHdc); }
//--------------------------------------------------------------------------- void __fastcall RestoreForm(UnicodeString Data, TForm * Form) { assert(Form); if (!Data.IsEmpty()) { Forms::TMonitor * Monitor = FormMonitor(Form); UnicodeString LeftStr = ::CutToChar(Data, L';', true); UnicodeString TopStr = ::CutToChar(Data, L';', true); UnicodeString RightStr = ::CutToChar(Data, L';', true); UnicodeString BottomStr = ::CutToChar(Data, L';', true); TWindowState State = (TWindowState)StrToIntDef(::CutToChar(Data, L';', true), (int)wsNormal); int PixelsPerInch = LoadPixelsPerInch(::CutToChar(Data, L';', true)); TRect Bounds = Form->BoundsRect; int Left = StrToDimensionDef(LeftStr, PixelsPerInch, Bounds.Left); int Top = StrToDimensionDef(TopStr, PixelsPerInch, Bounds.Top); bool DefaultPos = (Left == -1) && (Top == -1); if (!DefaultPos) { Bounds.Left = Left; Bounds.Top = Top; } else { Bounds.Left = 0; Bounds.Top = 0; } Bounds.Right = StrToDimensionDef(RightStr, PixelsPerInch, Bounds.Right); Bounds.Bottom = StrToDimensionDef(BottomStr, PixelsPerInch, Bounds.Bottom); Form->WindowState = State; if (State == wsNormal) { // move to the target monitor OffsetRect(Bounds, Monitor->Left, Monitor->Top); // reduce window size to that of monitor size // (this does not cut window into monitor!) if (Bounds.Width() > Monitor->WorkareaRect.Width()) { Bounds.Right -= (Bounds.Width() - Monitor->WorkareaRect.Width()); } if (Bounds.Height() > Monitor->WorkareaRect.Height()) { Bounds.Bottom -= (Bounds.Height() - Monitor->WorkareaRect.Height()); } if (DefaultPos || ((Bounds.Left < Monitor->Left) || (Bounds.Left > Monitor->Left + Monitor->WorkareaRect.Width() - 20) || (Bounds.Top < Monitor->Top) || (Bounds.Top > Monitor->Top + Monitor->WorkareaRect.Height() - 20))) { if (Monitor->Primary) { if ((Application->MainForm == NULL) || (Application->MainForm == Form)) { Form->Position = poDefaultPosOnly; } else { Form->Position = poOwnerFormCenter; } Form->Width = Bounds.Width(); Form->Height = Bounds.Height(); } else { // when positioning on non-primary monitor, we need // to handle that ourselves, so place window to center Form->SetBounds(Monitor->Left + ((Monitor->Width - Bounds.Width()) / 2), Monitor->Top + ((Monitor->Height - Bounds.Height()) / 2), Bounds.Width(), Bounds.Height()); Form->Position = poDesigned; } } else { Form->Position = poDesigned; Form->BoundsRect = Bounds; } } else if (State == wsMaximized) { Form->Position = poDesigned; Bounds = Form->BoundsRect; OffsetRect(Bounds, Monitor->Left, Monitor->Top); Form->BoundsRect = Bounds; } } else if (Form->Position == poDesigned) { Form->Position = poDefaultPosOnly; } }
void CDirectDraw::Render(SSurface Src) { LPDIRECTDRAWSURFACE2 lpDDSurface2 = NULL; LPDIRECTDRAWSURFACE2 pDDSurface = NULL; SSurface Dst; RECT srcRect; RECT dstRect = { 0, 512, 0, 448 }; DDSCAPS caps; ZeroMemory(&caps,sizeof(DDSCAPS)); caps.dwCaps = DDSCAPS_BACKBUFFER; if (lpDDSPrimary2->GetAttachedSurface (&caps, &pDDSurface) != DD_OK || pDDSurface == NULL) { lpDDSurface2 = lpDDSPrimary2; } else lpDDSurface2 = pDDSurface; lpDDSurface2 = lpDDSOffScreen2; if (!LockSurface2 (lpDDSurface2, &Dst)) return; if (!GUI.DepthConverted) { SSurface tmp; static BYTE buf [256 * 239 * 4*3*3]; tmp.Surface = buf; if(GUI.Scale == FILTER_NONE) { tmp.Pitch = Src.Pitch; tmp.Width = Src.Width; tmp.Height = Src.Height; } else { tmp.Pitch = Dst.Pitch; tmp.Width = Dst.Width; tmp.Height = Dst.Height; } RenderMethod (Src, tmp, &srcRect); ConvertDepth (&tmp, &Dst, &srcRect); } else { RenderMethod (Src, Dst, &srcRect); } if(!Settings.AutoDisplayMessages) { WinSetCustomDisplaySurface((void *)Dst.Surface, (Dst.Pitch*8/GUI.ScreenDepth), srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, GetFilterScale(GUI.Scale)); S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, GetFilterScale(GUI.Scale)); } RECT lastRect = SizeHistory [GUI.FlipCounter % GUI.NumFlipFrames]; POINT p; if (GUI.Stretch) { p.x = p.y = 0; ClientToScreen (GUI.hWnd, &p); GetClientRect (GUI.hWnd, &dstRect); // dstRect.bottom = int(double(dstRect.bottom) * double(239.0 / 240.0)); if(GUI.AspectRatio) { int width = dstRect.right - dstRect.left; int height = dstRect.bottom - dstRect.top; int oldWidth = GUI.AspectWidth; int oldHeight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; int newWidth, newHeight; if(oldWidth * height > oldHeight * width) { newWidth = width; newHeight = oldHeight*width/oldWidth; } else { newWidth = oldWidth*height/oldHeight; newHeight = height; } int xOffset = (width - newWidth)/2; int yOffset = (height - newHeight)/2; dstRect.right = dstRect.left + newWidth; dstRect.bottom = dstRect.top + newHeight; OffsetRect(&dstRect, p.x + xOffset, p.y + yOffset); } else { OffsetRect(&dstRect, p.x, p.y); } } else { GetClientRect (GUI.hWnd, &dstRect); int width = srcRect.right - srcRect.left; int height = srcRect.bottom - srcRect.top; //if (GUI.Scale == 1) //{ // width = MAX_SNES_WIDTH; // if (height < 240) // height *= 2; //} p.x = ((dstRect.right - dstRect.left) - width) >> 1; p.y = ((dstRect.bottom - dstRect.top) - height) >> 1; if(p.y < 0) p.y = 0; if(p.x < 0) p.x = 0; ClientToScreen (GUI.hWnd, &p); dstRect.top = p.y; dstRect.left = p.x; dstRect.bottom = dstRect.top + height; dstRect.right = dstRect.left + width; } lpDDSurface2->Unlock (Dst.Surface); ZeroMemory(&caps,sizeof(DDSCAPS)); caps.dwCaps = DDSCAPS_BACKBUFFER; if (lpDDSPrimary2->GetAttachedSurface (&caps, &pDDSurface) != DD_OK || pDDSurface == NULL) { lpDDSurface2 = lpDDSPrimary2; } else lpDDSurface2 = pDDSurface; // actually draw it onto the screen (unless in fullscreen mode; see UpdateBackBuffer() for that) while (lpDDSurface2->Blt (&dstRect, lpDDSOffScreen2, &srcRect, DDBLT_WAIT, NULL) == DDERR_SURFACELOST) lpDDSurface2->Restore (); RECT rect; DDBLTFX fx; memset (&fx, 0, sizeof (fx)); fx.dwSize = sizeof (fx); if (GUI.FlipCounter >= GUI.NumFlipFrames) { if (lastRect.top < dstRect.top) { rect.top = lastRect.top; rect.bottom = dstRect.top; rect.left = min(lastRect.left, dstRect.left); rect.right = max(lastRect.right, dstRect.right); lpDDSurface2->Blt (&rect, NULL, &rect, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } if (lastRect.bottom > dstRect.bottom) { rect.left = min(lastRect.left, dstRect.left); rect.right = max(lastRect.right, dstRect.right); rect.top = dstRect.bottom; rect.bottom = lastRect.bottom; lpDDSurface2->Blt (&rect, NULL, &rect, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } if (lastRect.left < dstRect.left) { rect.left = lastRect.left; rect.right = dstRect.left; rect.top = dstRect.top; rect.bottom = dstRect.bottom; lpDDSurface2->Blt (&rect, NULL, &rect, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } if (lastRect.right > dstRect.right) { rect.left = dstRect.right; rect.right = lastRect.right; rect.top = dstRect.top; rect.bottom = dstRect.bottom; lpDDSurface2->Blt (&rect, NULL, &rect, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } } lpDDSPrimary2->Flip (NULL, GUI.Vsync?DDFLIP_WAIT:DDFLIP_NOVSYNC); SizeHistory [GUI.FlipCounter % GUI.NumFlipFrames] = dstRect; }
//缺省消息响应函数,可被相应的流程继承 LRESULT CGameProcedure::MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { //-------------------------------------------------------------- // 处理一些缺省的消息 switch (message) { // 窗口大小发生改变 case WM_SIZE: { // 最小化 if( SIZE_MINIMIZED == wParam ) { m_bRenderingPaused = true; // 最小化时渲染暂停 m_bMinimized = true; m_bMaximized = FALSE; } // 最大化 else if( SIZE_MAXIMIZED == wParam ) { m_bRenderingPaused = FALSE; //恢复渲染工作(可能上一个状态时最小化) m_bMinimized = FALSE; m_bMaximized = true; HandlePossibleSizeChange( message, wParam, lParam); } // 恢复窗口 else if( SIZE_RESTORED == wParam ) { if( m_bMaximized ) // 刚才是最大化 { m_bMaximized = FALSE; HandlePossibleSizeChange(message, wParam, lParam); } else if( m_bMinimized ) // 刚才是最小化 { m_bRenderingPaused = FALSE; m_bMinimized = FALSE; HandlePossibleSizeChange(message, wParam, lParam); } else { //如果上一个状态既不是最大化也不是最小化,显然这次的WM_SIZE //消息是因为用户拖动窗口边缘引起的,这种情况我们并不马上恢复 //设备,我们等待用户停止拖动后在处理,也就是对WM_EXITSIZEMOVE //的处理... } } } break; // 用户拖动窗口开始 case WM_ENTERSIZEMOVE: { m_bRenderingPaused = true; } break; // 用户拖动中 case WM_SIZING: { RECT* pRect = (RECT*)lParam; switch(wParam) { case WMSZ_RIGHT: case WMSZ_BOTTOMRIGHT: { KeepWindowFOV(pRect, WMSZ_RIGHT, WMSZ_TOPLEFT); } break; case WMSZ_LEFT: case WMSZ_BOTTOMLEFT: { KeepWindowFOV(pRect, WMSZ_LEFT, WMSZ_TOPRIGHT); } break; case WMSZ_TOP: case WMSZ_TOPRIGHT: { KeepWindowFOV(pRect, WMSZ_TOP, WMSZ_BOTTOMLEFT); } break; case WMSZ_BOTTOM: { KeepWindowFOV(pRect, WMSZ_BOTTOM, WMSZ_TOPLEFT); } break; case WMSZ_TOPLEFT: { KeepWindowFOV(pRect, WMSZ_TOP, WMSZ_BOTTOMRIGHT); } break; } return TRUE; } break; // 窗口尺寸发生了改变后 case WM_WINDOWPOSCHANGING: { WINDOWPOS* pPos = (WINDOWPOS*)lParam; // 非大小改变 if(pPos->flags & SWP_NOSIZE || pPos->flags & SWP_DRAWFRAME) break; // 是“全屏”状态 if(s_pVariableSystem && s_pVariableSystem->GetAs_Int("View_FullScreen")) break; // 计算新的Client RECT rectFrame; SetRect(&rectFrame, 0, 0, pPos->cx, pPos->cy); OffsetRect(&rectFrame, pPos->x, pPos->y); RECT rectNewFrame; CopyRect(&rectNewFrame, &rectFrame); KeepWindowFOV(&rectNewFrame, -1, WMSZ_TOPLEFT); // 如果相同不处理 if(EqualRect(&rectFrame, &rectNewFrame)) break; pPos->x = rectNewFrame.left; pPos->y = rectNewFrame.top; pPos->cx = rectNewFrame.right-rectNewFrame.left; pPos->cy = rectNewFrame.bottom-rectNewFrame.top; return 0; } break; // 桌面分辨率改变 case WM_DISPLAYCHANGE: { if( s_pEventSystem && s_pVariableSystem->GetAs_Int("View_FullScreen")) { s_pEventSystem->PushEvent(GE_VARIABLE_CHANGED, "View_FullScreen", "1"); } // 重置分辨率 if(m_bMaximized) { ShowWindow(g_hMainWnd, SW_RESTORE); ShowWindow(g_hMainWnd, SW_MAXIMIZE); } else { s_pEventSystem->PushEvent(GE_VARIABLE_CHANGED, "View_Resoution", s_pVariableSystem->GetAs_String("View_Resoution").c_str()); } break; } // 用户拖动窗口边缘结束 case WM_EXITSIZEMOVE: { m_bRenderingPaused = FALSE; HandlePossibleSizeChange(message, wParam, lParam); // 设置分辨率变量 if(s_pVariableSystem) { RECT rect; GetClientRect(hWnd, &rect); char szTemp[MAX_PATH]; _snprintf(szTemp, MAX_PATH, "%d,%d", rect.right-rect.left, rect.bottom-rect.top); s_pVariableSystem->SetVariable("View_Resoution", szTemp, FALSE, FALSE); } } break; // 决定窗口最大最小尺寸 case WM_GETMINMAXINFO: { MINMAXINFO* pMinMaxInfo = (MINMAXINFO*)lParam; pMinMaxInfo->ptMinTrackSize.x = MINWINDOW_WIDTH; pMinMaxInfo->ptMinTrackSize.y = MINWINDOW_HEIGHT; // 最大尺寸为“窗口最大化”时的大小 RECT rect; SetRect(&rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); AdjustWindowRect(&rect, GetWindowStyle(g_hMainWnd), FALSE); pMinMaxInfo->ptMaxSize.x = rect.right-rect.left; pMinMaxInfo->ptMaxSize.y = rect.bottom-rect.top; pMinMaxInfo->ptMaxTrackSize.x = rect.right-rect.left; pMinMaxInfo->ptMaxTrackSize.y = rect.bottom-rect.top; } break; // 设置光标 case WM_SETCURSOR: { switch(LOWORD(lParam)) { case HTCLIENT: { if(s_pCursorMng) { s_pCursorMng->OnSetCursor(); return TRUE; } } break; default: break; } } break; // 窗口激活切换 case WM_ACTIVATEAPP: if( wParam == TRUE ) { m_bActive = TRUE; } else { m_bActive = FALSE; } // 通知输入器 if(s_pInputSystem) ((CInputSystem*)s_pInputSystem)->OnActiveApp(m_bActive); break; // 消息主循环移到菜单中 case WM_ENTERMENULOOP: { m_bRenderingPaused = true; } break; // 消息主循环移出菜单 case WM_EXITMENULOOP: { m_bRenderingPaused = FALSE; } break; // 系统按键 case WM_SYSCOMMAND: { switch(wParam) { // 屏蔽F10 case SC_KEYMENU: return 1; default: break; } } break; // 窗口重绘消息 case WM_PAINT: { PAINTSTRUCT psStruct; ::BeginPaint(hWnd, &psStruct); ::EndPaint(hWnd, &psStruct); s_pGfxSystem->OnPaint(); } break; // 窗口背景刷 case WM_ERASEBKGND: { return 1; } break; // 处理玩家的退出请求 case WM_CLOSE: { //AxProfile::AxProfile_Report(); // 主流程中,弹出设置菜单 if(GetActiveProcedure() == s_pProcMain && s_pUISystem) { if(wParam==0xC0DE && lParam==0XC0DE) { ProcessCloseRequest(); break; } else { s_pEventSystem->PushEvent( GE_TOGLE_SYSTEMFRAME ); return TRUE; } } } break; // 窗口销毁 case WM_DESTROY: { PostQuitMessage(0); } break; // 输入法改变 case WM_INPUTLANGCHANGE: { if(s_pEventSystem) { s_pEventSystem->PushEvent(GE_CHAT_INPUTLANGUAGE_CHANGE); } } break; case WM_IME_NOTIFY: { if(wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) { if(s_pEventSystem) { s_pEventSystem->PushEvent(GE_CHAT_INPUTLANGUAGE_CHANGE); } } } break; default: break; } return DefWindowProc( hWnd, message, wParam, lParam ); }
VOID CGameProcedure::CreateMainWnd(VOID) { INT nWinWidth = 0; INT nWinHeight = 0; if( s_pVariableSystem ) { BOOL bHave = FALSE; fVector2 fResoution = CVariableSystem::GetMe()->GetAs_Vector2( "View_Resoution" , &bHave); if (bHave) { nWinWidth = (INT)fResoution.x; nWinHeight = (INT)fResoution.y; } else { nWinWidth = DEFWINDOW_WIDTH; nWinHeight = DEFWINDOW_HEIGHT; } } else { nWinWidth = DEFWINDOW_WIDTH; nWinHeight = DEFWINDOW_HEIGHT; } // 计算窗口大小 m_bMinimized = FALSE; m_bFullScreen = TRUE; SetRect( &m_rectWindow, 0, 0, nWinWidth, nWinHeight ); AdjustWindowRect( &m_rectWindow, DEFWINDOW_STYLE, FALSE ); SetRect( &m_rectFCOffset, m_rectWindow.left, m_rectWindow.top, m_rectWindow.right - nWinWidth, m_rectWindow.bottom - nWinHeight ); UINT dwX = (::GetSystemMetrics(SM_CXFULLSCREEN)-(m_rectWindow.right-m_rectWindow.left))/2; UINT dwY = (::GetSystemMetrics(SM_CYFULLSCREEN)-(m_rectWindow.bottom-m_rectWindow.top))/2; OffsetRect(&m_rectWindow, -m_rectFCOffset.left, -m_rectFCOffset.top); OffsetRect(&m_rectWindow, dwX, dwY); m_bActive = true; m_bRenderingPaused = FALSE; // 注册窗口类 WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wcex.lpfnWndProc = (WNDPROC)_MainWndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(g_hInstance, (LPCTSTR)IDD_GAME_DIALOG); wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); wcex.hbrBackground = (HBRUSH)NULL; //GetStockObject(WHITE_BRUSH); wcex.lpszMenuName = (LPCTSTR)NULL; wcex.lpszClassName = MAINWINDOW_CLASS; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); RegisterClassEx(&wcex); // 创建窗口 CHAR szTitle[MAX_PATH]; _snprintf(szTitle, MAX_PATH, "%s %s (%s %s)", GAME_TITLE, VERSION_INFO, __DATE__, __TIME__); HWND hWnd = CreateWindowEx( NULL, MAINWINDOW_CLASS, szTitle, DEFWINDOW_STYLE, m_rectWindow.left, m_rectWindow.top, m_rectWindow.right-m_rectWindow.left, m_rectWindow.bottom-m_rectWindow.top, NULL, NULL, g_hInstance, NULL); if(!hWnd) { KLThrow(_T("Can't create main window!")); } ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); g_hMainWnd = hWnd; }
void henon_tweaker(void) { int i; char chosen_file[128]; rect R; rect tR; int last_time; int keyword; int current_item; int centerx, centery; int height, width; int row; static int lefters[] = { 1, 2, 0, 4, 3, 5, 12, 6, 7, 8, 9, 10, 11, 15, 13, 14 }; static int righters[] = { 1, 2, 0, 4, 3, 5, 7, 8, 9, 10, 11, 12, 6, 14, 15, 13 }; static int uppers[] = { 13, 14, 15, 0, 2, 3, 5, 5, 5, 5, 5, 5, 5, 6, 8, 11 }; static int downers[] = { 3, 3, 4, 5, 5, 8, 13, 13, 13, 14, 14, 15, 15, 0, 1, 2 }; our_flocktype = flocktype; our_tracetype = tracetype; henon_slider.value = fha; height = 2 + FontHeight + 8 + 2 * (3 * FontHeight / 2) + slider_height(&henon_slider) + 4 + 2 * FontHeight + 4; width = 2 * sR.Xmax / 3; HideCursor(); PushCursorPosition(); BasicCenteredBox(&tR, width, height, LIGHTGRAY, "Hnon Tweaks", BLACK); Centers(&tR, ¢erx, ¢ery); PushMouseRectLimit(&tR); items = 0; R.Xmin = tR.Xmin + 4 + StringWidth("Flock Size: ") + 4; R.Xmax = tR.Xmax - 4; R.Ymin = row = tR.Ymin + FontHeight + 8; R.Ymax = R.Ymin + FontHeight + 4; JString("Flock size: ", R.Xmin - 2, R.Ymin + 2, BLACK, LIGHTGRAY, alignRight, alignTop); CreateRadioPanel(&R, SML, flocktypeR, 3, our_flocktype); for (i = 0; i < 3; i++) bR[items++] = &flocktypeR[i]; OffsetRect(&R, 0, 3 * FontHeight / 2); R.Xmin = centerx; row = R.Ymin; JString("Trace Type: ", R.Xmin - 2, R.Ymin + 2, BLACK, LIGHTGRAY, alignRight, alignTop); CreateRadioPanel(&R, PL, tracetypeR, 2, our_tracetype); for (i = 0; i < 2; i++) bR[items++] = &tracetypeR[i]; row += 3 * FontHeight / 2; create_slider(&henon_slider, &tR, 4, row - tR.Ymin); bR[items++] = &henon_slider.bR; bR[items++] = &henon_slider.TB.nR; for (i = 0; i < 6; i++) bR[items++] = &henon_slider.zR[i]; if (!fancyflag) { R = henon_slider.tR; InsetRect(&R, 1, 1); GrayOut(&R); } row = henon_slider.tR.Ymax + FontHeight; R.Xmin = tR.Xmin + 4; R.Xmax = tR.Xmax - 4; R.Ymin = row; R.Ymax = row + FontHeight + 4; CreateRadioPanel(&R, standard_button_texts, doitR, 3, -1); for (i = 0; i < 3; i++) bR[items++] = &doitR[i]; current_item = items - 1; push(current_item, true); move_to_corner(bR[current_item]); ShowCursor(); while (1) { event e; int n = KeyEvent(false, &e); int button = (e.State & 0x700) >> 8; int X = e.CursorX; int Y = e.CursorY; int last_item = current_item; slider *current_slider = NULL; if (fancyflag && XYInRect(X, Y, &henon_slider.tR)) current_slider = &henon_slider; keyword = 0; if (n) last_time = e.Time; else { if (e.Time - last_time > 5) { if (button) n = 1; else last_time = e.Time; } } if (n) { keyword = ShiftArrows(&e); if (button == swRight) keyword = 0x1b; if (!keyword) { if (e.ASCII && e.ASCII != 0xe0) keyword = e.ASCII; else keyword = e.ScanCode << 8; } if (button == swLeft) { keyword = 0x0d; if (current_slider) { if (XYInRect(X, Y, ¤t_slider->bR)) { PushMouseRectLimit(¤t_slider->sR); while (button == swLeft) { reposition_slider_X(current_slider, X, false); KeyEvent(false, &e); button = (e.State & 0x700) >> 8; X = e.CursorX; Y = e.CursorY; } PopMouseRect(); keyword = 0; } else if (XYInRect(X, Y, ¤t_slider->sR)) { reposition_slider_X(current_slider, X, false); keyword = 0; } } }
static void scrollbar_test4(void) { BOOL ret; SCROLLBARINFO sbi; RECT rect; BOOL (WINAPI *pGetScrollBarInfo)(HWND, LONG, LPSCROLLBARINFO); pGetScrollBarInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetScrollBarInfo"); if (!pGetScrollBarInfo) { win_skip("GetScrollBarInfo is not available\n"); return; } /* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen * coordinates. */ sbi.cbSize = sizeof(sbi); ret = pGetScrollBarInfo( hScroll, OBJID_CLIENT, &sbi); ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); GetWindowRect( hScroll, &rect ); ok( ret, "The GetWindowRect() call should not fail.\n" ); ok( !(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)), "unexpected rgstate(0x%x)\n", sbi.rgstate[0]); ok( EqualRect(&rect, &sbi.rcScrollBar), "WindowRect(%d, %d, %d, %d) != rcScrollBar(%d, %d, %d, %d)\n", rect.top, rect.left, rect.bottom, rect.right, sbi.rcScrollBar.top, sbi.rcScrollBar.left, sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); /* Test windows horizontal and vertical scrollbar to make sure rcScrollBar * is still returned in screen coordinates by moving the window, and * making sure that it shifts the rcScrollBar value. */ ShowWindow( hMainWnd, SW_SHOW ); sbi.cbSize = sizeof(sbi); ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi); ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); GetWindowRect( hMainWnd, &rect ); ok( ret, "The GetWindowRect() call should not fail.\n" ); MoveWindow( hMainWnd, rect.left+5, rect.top+5, rect.right-rect.left, rect.bottom-rect.top, TRUE ); rect = sbi.rcScrollBar; OffsetRect(&rect, 5, 5); ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi); ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); ok( EqualRect(&rect, &sbi.rcScrollBar), "PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n", rect.top, rect.left, rect.bottom, rect.right, sbi.rcScrollBar.top, sbi.rcScrollBar.left, sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); sbi.cbSize = sizeof(sbi); ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi); ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); GetWindowRect( hMainWnd, &rect ); ok( ret, "The GetWindowRect() call should not fail.\n" ); MoveWindow( hMainWnd, rect.left+5, rect.top+5, rect.right-rect.left, rect.bottom-rect.top, TRUE ); rect = sbi.rcScrollBar; OffsetRect(&rect, 5, 5); ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi); ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); ok( EqualRect(&rect, &sbi.rcScrollBar), "PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n", rect.top, rect.left, rect.bottom, rect.right, sbi.rcScrollBar.top, sbi.rcScrollBar.left, sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); }
OSErr SetupPickMonitorPane(ControlRef inPane, DisplayIDType inDefaultMonitor) { GDHandle dev = GetDeviceList(); OSErr err = noErr; // make the default monitor the selected device if (inDefaultMonitor) DMGetGDeviceByDisplayID(inDefaultMonitor, &sSelectedDevice, true); else sSelectedDevice = GetMainDevice(); // build the list of monitors sNumMonitors = 0; while (dev && sNumMonitors < kMaxMonitors) { if (TestDeviceAttribute(dev, screenDevice) && TestDeviceAttribute(dev, screenActive)) { sMonitors[sNumMonitors].device = dev; sMonitors[sNumMonitors].origRect = (**dev).gdRect; sMonitors[sNumMonitors].isMain = (dev == GetMainDevice()); sNumMonitors++; } dev = GetNextDevice(dev); } // calculate scaled rects if (sNumMonitors) { Rect origPaneRect, paneRect; Rect origGrayRect, grayRect, scaledGrayRect; float srcAspect, dstAspect, scale; int i; GetControlBounds(inPane, &origPaneRect); paneRect = origPaneRect; OffsetRect(&paneRect, -paneRect.left, -paneRect.top); GetRegionBounds(GetGrayRgn(), &origGrayRect); grayRect = origGrayRect; OffsetRect(&grayRect, -grayRect.left, -grayRect.top); srcAspect = (float)grayRect.right / (float)grayRect.bottom; dstAspect = (float)paneRect.right / (float)paneRect.bottom; scaledGrayRect = paneRect; if (srcAspect < dstAspect) { scaledGrayRect.right = (float)paneRect.bottom * srcAspect; scale = (float)scaledGrayRect.right / grayRect.right; } else { scaledGrayRect.bottom = (float)paneRect.right / srcAspect; scale = (float)scaledGrayRect.bottom / grayRect.bottom; } for (i = 0; i < sNumMonitors; i++) { Rect r = sMonitors[i].origRect; Rect r2 = r; // normalize rect and scale OffsetRect(&r, -r.left, -r.top); r.bottom = (float)r.bottom * scale; r.right = (float)r.right * scale; // offset rect wrt gray region OffsetRect(&r, (float)(r2.left - origGrayRect.left) * scale, (float)(r2.top - origGrayRect.top) * scale); sMonitors[i].scaledRect = r; } // center scaledGrayRect in the pane OffsetRect(&scaledGrayRect, (paneRect.right - scaledGrayRect.right) / 2, (paneRect.bottom - scaledGrayRect.bottom) / 2); // offset monitors to match for (i = 0; i < sNumMonitors; i++) OffsetRect(&sMonitors[i].scaledRect, scaledGrayRect.left, scaledGrayRect.top); } else return paramErr; // setup the procs for the pick monitor user pane err = SetupUserPaneProcs(inPane, drawProc, hitTestProc, trackingProc); return err; }
//-------------------------------------------------------------------------------------- DXUTAPI void CDXUTIMEEditBox::RenderComposition() { s_CompString.SetText(ImeUi_GetCompositionString()); RECT rcCaret = { 0, 0, 0, 0 }; int nX, nXFirst; m_Buffer.CPtoX(m_nCaret, FALSE, &nX); m_Buffer.CPtoX(m_nFirstVisible, FALSE, &nXFirst); CDXUTElement* pElement = m_Elements[1]; // Get the required width RECT rc = { m_rcText.left + nX - nXFirst, m_rcText.top, m_rcText.left + nX - nXFirst, m_rcText.bottom }; m_pDialog->CalcTextRect(s_CompString.GetBuffer(), pElement, &rc); // If the composition string is too long to fit within // the text area, move it to below the current line. // This matches the behavior of the default IME. if (rc.right > m_rcText.right) OffsetRect(&rc, m_rcText.left - rc.left, rc.bottom - rc.top); // Save the rectangle position for processing highlighted text. RECT rcFirst = rc; // Update s_ptCompString for RenderCandidateReadingWindow(). s_ptCompString.x = rc.left; s_ptCompString.y = rc.top; DWORD TextColor = m_CompColor; // Render the window and string. // If the string is too long, we must wrap the line. pElement->FontColor.SetCurrent(TextColor); const WCHAR* pwszComp = s_CompString.GetBuffer(); int nCharLeft = s_CompString.GetTextSize(); for (;;) { // Find the last character that can be drawn on the same line. int nLastInLine; int bTrail; s_CompString.XtoCP(m_rcText.right - rc.left, &nLastInLine, &bTrail); int nNumCharToDraw = std::min(nCharLeft, nLastInLine); m_pDialog->CalcTextRect(pwszComp, pElement, &rc, nNumCharToDraw); // Draw the background // For Korean IME, blink the composition window background as if it // is a cursor. if (GetPrimaryLanguage() == LANG_KOREAN) { if (m_bCaretOn) { m_pDialog->DrawRect(&rc, m_CompWinColor); } else { // Not drawing composition string background. We // use the editbox's text color for composition // string text. TextColor = m_Elements[0]->FontColor.States[DXUT_STATE_NORMAL]; } } else { // Non-Korean IME. Always draw composition background. m_pDialog->DrawRect(&rc, m_CompWinColor); } // Draw the text pElement->FontColor.SetCurrent(TextColor); m_pDialog->DrawText(pwszComp, pElement, &rc, false); // Advance pointer and counter nCharLeft -= nNumCharToDraw; pwszComp += nNumCharToDraw; if (nCharLeft <= 0) break; // Advance rectangle coordinates to beginning of next line OffsetRect(&rc, m_rcText.left - rc.left, rc.bottom - rc.top); } // Load the rect for the first line again. rc = rcFirst; // Inspect each character in the comp string. // For target-converted and target-non-converted characters, // we display a different background color so they appear highlighted. int nCharFirst = 0; nXFirst = 0; s_nFirstTargetConv = -1; BYTE* pAttr; const WCHAR* pcComp; for (pcComp = s_CompString.GetBuffer(), pAttr = ImeUi_GetCompStringAttr(); *pcComp != L'\0'; ++pcComp, ++pAttr) { DWORD bkColor; // Render a different background for this character int nXLeft, nXRight; s_CompString.CPtoX(int(pcComp - s_CompString.GetBuffer()), FALSE, &nXLeft); s_CompString.CPtoX(int(pcComp - s_CompString.GetBuffer()), TRUE, &nXRight); // Check if this character is off the right edge and should // be wrapped to the next line. if (nXRight - nXFirst > m_rcText.right - rc.left) { // Advance rectangle coordinates to beginning of next line OffsetRect(&rc, m_rcText.left - rc.left, rc.bottom - rc.top); // Update the line's first character information nCharFirst = int(pcComp - s_CompString.GetBuffer()); s_CompString.CPtoX(nCharFirst, FALSE, &nXFirst); } // If the caret is on this character, save the coordinates // for drawing the caret later. if (ImeUi_GetImeCursorChars() == (DWORD)(pcComp - s_CompString.GetBuffer())) { rcCaret = rc; rcCaret.left += nXLeft - nXFirst - 1; rcCaret.right = rcCaret.left + 2; } // Set up color based on the character attribute if (*pAttr == ATTR_TARGET_CONVERTED) { pElement->FontColor.SetCurrent(m_CompTargetColor); bkColor = m_CompTargetBkColor; } else if (*pAttr == ATTR_TARGET_NOTCONVERTED) { pElement->FontColor.SetCurrent(m_CompTargetNonColor); bkColor = m_CompTargetNonBkColor; } else { continue; } RECT rcTarget = { rc.left + nXLeft - nXFirst, rc.top, rc.left + nXRight - nXFirst, rc.bottom }; m_pDialog->DrawRect(&rcTarget, bkColor); m_pDialog->DrawText(pcComp, pElement, &rcTarget, false, 1); // Record the first target converted character's index if (-1 == s_nFirstTargetConv) s_nFirstTargetConv = int(pAttr - ImeUi_GetCompStringAttr()); } // Render the composition caret if (m_bCaretOn) { // If the caret is at the very end, its position would not have // been computed in the above loop. We compute it here. if (ImeUi_GetImeCursorChars() == (DWORD)s_CompString.GetTextSize()) { s_CompString.CPtoX(ImeUi_GetImeCursorChars(), FALSE, &nX); rcCaret = rc; rcCaret.left += nX - nXFirst - 1; rcCaret.right = rcCaret.left + 2; } m_pDialog->DrawRect(&rcCaret, m_CompCaretColor); } }
BOOL CCustomMenu::OnDrawItem(WPARAM wParam,LPARAM lParam) { DRAWITEMSTRUCT *pDrawItem = NULL; HBRUSH hBrush; MENUITEMINFO mi; TCHAR szMenuString[64]; RECT rcText; RECT rcShortcut; UINT MenuState; TCHAR szMenuName[64]; TCHAR szMenuShortcut[64]; TCHAR *ptr = NULL; DWORD dwPrefixState; int i = 0; pDrawItem = (DRAWITEMSTRUCT *)lParam; /* Is this item actually a menu? */ if(pDrawItem->CtlType == ODT_MENU) { if(pDrawItem->itemAction & ODA_DRAWENTIRE || (pDrawItem->itemAction & ODA_SELECT)) { if(pDrawItem->itemState & ODS_SELECTED) { /* <---- Item been selected ----> */ COLORREF BorderColorBase; RECT rcSelection; BorderColorBase = GetSysColor(COLOR_MENUHILIGHT); hBrush = CreateSolidBrush(BORDER_SELECTION_COLOUR); /* Draw the frame around the menu. */ FrameRect(pDrawItem->hDC,&pDrawItem->rcItem,hBrush); DeleteObject(hBrush); rcSelection = pDrawItem->rcItem; /* Decrease the width and height of the shaded rectangle so that the border will be seen around the shading. */ InflateRect(&rcSelection,-1,-1); Gdiplus::SolidBrush SemiTransBrush(Gdiplus::Color(100,GetRValue(BorderColorBase), GetGValue(BorderColorBase),GetBValue(BorderColorBase))); Gdiplus::Graphics graphics(pDrawItem->hDC); graphics.FillRectangle(&SemiTransBrush,rcSelection.left,rcSelection.top, rcSelection.right - rcSelection.left,rcSelection.bottom - rcSelection.top); } else if(!(pDrawItem->itemState & ODS_SELECTED)) { COLORREF MenuBackColor; MenuBackColor = GetSysColor(COLOR_MENU); /* <---- Item been deselected ----> */ hBrush = CreateSolidBrush(MenuBackColor); /* Fill the menu item with the backing colour. */ FillRect(pDrawItem->hDC,&pDrawItem->rcItem,hBrush); DeleteObject(hBrush); } SetBkMode(pDrawItem->hDC,TRANSPARENT); MenuState = GetMenuState((HMENU)pDrawItem->hwndItem,pDrawItem->itemID,MF_BYCOMMAND); /* A different colour is used for all text on the menu when it is disabled. */ if(MenuState & MF_GRAYED) SetTextColor(pDrawItem->hDC,GetSysColor(COLOR_GRAYTEXT)); /* If this item is a separator, draw in the separator line. */ if((MenuState & MF_SEPARATOR) && !(MenuState & MF_POPUP) || MenuState == (UINT)-1) { RECT rcSeparator; rcSeparator = pDrawItem->rcItem; OffsetRect(&rcSeparator,0,(rcSeparator.bottom - rcSeparator.top) / 2); //OffsetRect(&rcSeparator,MENU_TEXT_INDENT_LEFT,(rcSeparator.bottom - rcSeparator.top) / 2); DrawEdge(pDrawItem->hDC,&rcSeparator,EDGE_ETCHED,BF_TOP); } /* If the item is checked, draw a checkmark to the left of the menu text. */ if(MenuState & MF_CHECKED) { /* Draw a check mark next to the menu. */ /* SHELLIMAGES_MENUCHECKMARK - Defined within Explorer++ project. */ ImageList_Draw(himlMenu,21,pDrawItem->hDC, pDrawItem->rcItem.left + MENU_ICON_INDENT_LEFT, pDrawItem->rcItem.top + MENU_ICON_INDENT_TOP,ILD_NORMAL); } mi.cbSize = sizeof(mi); mi.fMask = MIIM_DATA; GetMenuItemInfo((HMENU)pDrawItem->hwndItem,pDrawItem->itemID,FALSE,&mi); CustomMenuInfo_t *pcmi = NULL; pcmi = (CustomMenuInfo_t *)mi.dwItemData; if(pcmi->bUseImage) { ImageList_Draw(himlMenu,pcmi->iImage,pDrawItem->hDC, pDrawItem->rcItem.left + MENU_ICON_INDENT_LEFT, pDrawItem->rcItem.top + MENU_ICON_INDENT_TOP,ILD_NORMAL); } GetMenuString((HMENU)pDrawItem->hwndItem,pDrawItem->itemID, szMenuString,SIZEOF_ARRAY(szMenuString),MF_BYCOMMAND); ptr = szMenuString; /* Read out the main part of the menu text. This will either be until the end of the string, or until a tab character is reached (depending on whether or not there is a shortcut string in the menu text). */ while(*ptr != '\0' && *ptr != '\t') { szMenuName[i] = *ptr; i++; ptr++; } szMenuName[i] = '\0'; i = 0; /* Now, read out the menu shortcut text (if any). */ if(*ptr == '\t') { ptr++; while(*ptr != '\0') { szMenuShortcut[i] = *ptr; i++; ptr++; } } szMenuShortcut[i] = '\0'; /* Check whether or not the accelerator mnemonics need to be underlined. */ if(pDrawItem->itemState & ODS_NOACCEL) dwPrefixState = DT_HIDEPREFIX; else dwPrefixState = 0; rcText = pDrawItem->rcItem; OffsetRect(&rcText,MENU_TEXT_INDENT_LEFT,0); /* Draw the main menu text. */ DrawText(pDrawItem->hDC,szMenuName,lstrlen(szMenuName),&rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_EXPANDTABS|dwPrefixState); /* The menu text bounding rectangle does not extend the full width of the menu. There is a small clearance on the right edge to ensure all text is drawn well before the end of the menu. */ rcShortcut = pDrawItem->rcItem; InflateRect(&rcShortcut,MENU_TEXT_INDENT_RIGHT,0); /* Now draw the menu shortcut text (if any). */ DrawText(pDrawItem->hDC,szMenuShortcut,lstrlen(szMenuShortcut),&rcShortcut, DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_HIDEPREFIX); } } return TRUE; }
VOID CGameProcedure::CreateMainWnd(VOID) { //------------------------------------------------------ //计算窗口大小 m_bMinimized = FALSE; m_bFullScreen = TRUE; fVector2 fResoution; if (CGameProcedure::s_pVariableSystem->GetAs_Int("View_FullScreen")) { fResoution.x = (float)::GetSystemMetrics(SM_CXSCREEN); fResoution.y = (float)::GetSystemMetrics(SM_CYSCREEN); } else { fResoution = s_pVariableSystem->GetAs_Vector2("View_Resoution"); } CGameProcedure::m_fWindowFOV = fResoution.x / fResoution.y; SetRect(&m_rectWindow, 0, 0, (int)fResoution.x, (int)fResoution.y); AdjustWindowRect(&m_rectWindow, DEFWINDOW_STYLE, FALSE); SetRect(&m_rectFCOffset, m_rectWindow.left, m_rectWindow.top, m_rectWindow.right-(int)fResoution.x, m_rectWindow.bottom-(int)fResoution.y); UINT dwX = (::GetSystemMetrics(SM_CXFULLSCREEN)-(m_rectWindow.right-m_rectWindow.left))/2; UINT dwY = (::GetSystemMetrics(SM_CYFULLSCREEN)-(m_rectWindow.bottom-m_rectWindow.top))/2; OffsetRect(&m_rectWindow, -m_rectFCOffset.left, -m_rectFCOffset.top); OffsetRect(&m_rectWindow, dwX, dwY); m_bActive = true; m_bRenderingPaused = FALSE; //------------------------------------------------------ //注册窗口类 WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wcex.lpfnWndProc = (WNDPROC)_MainWndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(g_hInstance, (LPCTSTR)IDD_GAME_DIALOG); wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); wcex.hbrBackground = (HBRUSH)NULL; //GetStockObject(WHITE_BRUSH); wcex.lpszMenuName = (LPCTSTR)NULL; wcex.lpszClassName = MAINWINDOW_CLASS; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); RegisterClassEx(&wcex); //------------------------------------------------------ //创建窗口 CHAR szTitle[MAX_PATH]; _snprintf(szTitle, MAX_PATH, "%s %s (%s %s)", GAME_TITLE, VERSION_INFO, __DATE__, __TIME__); HWND hWnd = CreateWindowEx(NULL, MAINWINDOW_CLASS, szTitle, DEFWINDOW_STYLE, m_rectWindow.left, m_rectWindow.top, m_rectWindow.right-m_rectWindow.left, m_rectWindow.bottom-m_rectWindow.top, NULL, NULL, g_hInstance, NULL); if (!hWnd) { TDThrow(_T("Can't create main window!")); } if (CGameProcedure::s_pVariableSystem->GetAs_Int("View_FullScreen")) { s_pEventSystem->PushEvent(GE_VARIABLE_CHANGED, "View_FullScreen", "1"); s_pEventSystem->PushEvent(GE_CHAT_ADJUST_MOVE_CTL, (INT)fResoution.x, (INT)fResoution.y); }else { const STRING& strVariable = CGameProcedure::s_pVariableSystem->GetAs_String("View_Resoution"); s_pEventSystem->PushEvent(GE_VARIABLE_CHANGED,"View_Resoution", strVariable.c_str()); s_pEventSystem->PushEvent(GE_CHAT_ADJUST_MOVE_CTL, (INT)fResoution.x, (INT)fResoution.y); } ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); g_hMainWnd = hWnd; }
/** * name: PaintThemeButton * desc: Draws the none themed button * param: ctl - BTNCTRL structure for the button * hdcMem - device context to draw to * rcClient - rectangle of the whole button * return: nothing **/ static void __fastcall PaintButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) { RECT rcText = { 0, 0, 0, 0 }; TCHAR szText[MAX_PATH] = { 0 }; WORD ccText; // Draw the flat button if (ctl->dwStyle & MBS_FLAT) { HBRUSH hbr = NULL; if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); if (dc = GetDC(hwndParent)) { hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); ReleaseDC(hwndParent, dc); } } if (hbr) { FillRect(hdcMem, rcClient, hbr); DeleteObject(hbr); } if (ctl->stateId == PBS_HOT || ctl->bFocus) { if (ctl->pbState) DrawEdge(hdcMem, rcClient, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, rcClient, BDR_RAISEDOUTER, BF_RECT | BF_SOFT | BF_FLAT); } else if (ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, rcClient, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } else { UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if (ctl->defbutton&&ctl->stateId == PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, rcClient, DFC_BUTTON, uState); // Draw focus rectangle if button has focus if (ctl->bFocus) { RECT focusRect = *rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // calculate text rect { SIZE sizeText; HFONT hOldFont; ccText = GetWindowText(ctl->hwnd, szText, _countof(szText)); if (ccText > 0) { hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); GetTextExtentPoint32(hdcMem, szText, ccText, &sizeText); if (ctl->cHot) { SIZE sizeHot; GetTextExtentPoint32A(hdcMem, "&", 1, &sizeHot); sizeText.cx -= sizeHot.cx; } SelectObject(hdcMem, hOldFont); rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - sizeText.cx) / 2; rcText.top = (rcClient->bottom - rcClient->top - sizeText.cy) / 2; rcText.right = rcText.left + sizeText.cx; rcText.bottom = rcText.top + sizeText.cy; if (ctl->stateId == PBS_PRESSED) OffsetRect(&rcText, 1, 1); } } PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); // draw text if (ccText > 0) { HFONT hOldFont; hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); SetBkMode(hdcMem, TRANSPARENT); SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? ctl->stateId == PBS_HOT ? GetSysColor(COLOR_HOTLIGHT) : GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); DrawState(hdcMem, NULL, NULL, (LPARAM)szText, 0, rcText.left, rcText.top, rcText.right - rcText.left, rcText.bottom - rcText.top, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); SelectObject(hdcMem, hOldFont); } }
BOOL cAnimationManager::MagProcess(RECT * dockingBarRect, cWindow* window, VECTOR2 * outWindowPos) { BOOL rt = FALSE; if( abs( (int)(dockingBarRect->left - (LONG)(window->GetAbsX()) ) ) <= MAG_GAB ) { outWindowPos->x = (float)dockingBarRect->left; rt = TRUE; } else if(abs((int)(dockingBarRect->left - (window->GetAbsX()+window->GetWidth()))) <= MAG_GAB) { outWindowPos->x = (float)dockingBarRect->left-window->GetWidth(); rt = TRUE; } if(abs((int)(dockingBarRect->right - window->GetAbsX())) <= MAG_GAB) { outWindowPos->x = (float)dockingBarRect->right; rt = TRUE; } else if(abs((int)(dockingBarRect->right - (window->GetAbsX()+window->GetWidth()))) <= MAG_GAB) { outWindowPos->x = (float)(dockingBarRect->right - window->GetWidth()); rt = TRUE; } if(abs((int)(dockingBarRect->top - window->GetAbsY())) <= MAG_GAB) { outWindowPos->y = (float)dockingBarRect->top; rt = TRUE; } else if(abs((int)(dockingBarRect->top - (window->GetAbsY()+window->GetHeight()))) <= MAG_GAB) { outWindowPos->y = (float)dockingBarRect->top-window->GetHeight(); rt = TRUE; } if(abs((int)(dockingBarRect->bottom - window->GetAbsY())) <= MAG_GAB) { outWindowPos->y = (float)dockingBarRect->bottom; rt = TRUE; } else if(abs((int)(dockingBarRect->bottom - (window->GetAbsY()+window->GetHeight()))) <= MAG_GAB) { outWindowPos->y = (float)(dockingBarRect->bottom - window->GetHeight()); rt = TRUE; } //KES 031017 CAPTION이 밖으로 나가지 못하도록 RECT rc = *((cDialog*)window)->GetCaptionRect(); OffsetRect( &rc, (int)window->GetAbsX(), (int)window->GetAbsY() ); if( rc.left < dockingBarRect->left ) { outWindowPos->x = (float)dockingBarRect->left; rt = TRUE; } else if( rc.right > dockingBarRect->right ) { outWindowPos->x = (float)(dockingBarRect->right - ( rc.right - rc.left )); rt = TRUE; } if( rc.top < dockingBarRect->top ) { outWindowPos->y = (float)dockingBarRect->top; rt = TRUE; } else if( rc.bottom > dockingBarRect->bottom ) { outWindowPos->y = (float)(dockingBarRect->bottom - ( rc.bottom - rc.top )); rt = TRUE; } return rt; }
/* * DescDialogProc: Dialog procedure for dialog containing an * item's long description. */ BOOL CALLBACK DescDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { DescDialogStruct *info; static HWND hwndBitmap; static Bool changed; // True when player has changed description HWND hEdit, hwndOK, hURL, hFixed; HDC hdc; HFONT hFont; RECT dlg_rect, edit_rect, fixed_rect; AREA area; char *desc, *str, url[MAX_URL + 1], *pPageBreak; DRAWITEMSTRUCT *lpdis; char descriptionBuffer[MAX_PAGE_DESCRIPTION_TEXT+1]; int height; info = (DescDialogStruct *) GetWindowLong(hDlg, DWL_USER); switch (message) { case WM_INITDIALOG: info = (DescDialogStruct *) lParam; /* Store structure in dialog box's extra bytes */ SetWindowLong(hDlg, DWL_USER, (long) info); hwndBitmap = GetDlgItem(hDlg, IDC_DESCBITMAP); hFixed = GetDlgItem(hDlg, IDC_DESCFIXED); hEdit = GetDlgItem(hDlg, IDC_DESCBOX); hwndOK = GetDlgItem(hDlg, IDOK); // Item Name. height = SetFontToFitText(info,GetDlgItem(hDlg, IDC_DESCNAME), (int)FONT_TITLES, info->name); SetDlgItemText(hDlg, IDC_DESCNAME, info->name); hdc = GetDC(hDlg); SetTextColor(hdc,GetPlayerNameColor(info->obj,info->name)); ReleaseDC(hDlg,hdc); // Item Description. hFont = GetFont(FONT_EDIT); SetWindowFont(hFixed, hFont, FALSE); SetWindowFont(hEdit, hFont, FALSE); str = info->description; if (str) { pPageBreak = strchr(str,PAGE_BREAK_CHAR); while (pPageBreak) { info->numPages++; str = pPageBreak+1; pPageBreak = strchr(str,PAGE_BREAK_CHAR); } info->numPages++; GetPageText(descriptionBuffer,info); Edit_SetText(hEdit, descriptionBuffer); } // Show fixed string, if appropriate if (info->fixed_string != NULL) { SetDlgItemText(hDlg, IDC_DESCFIXED, info->fixed_string); SetWindowFont(GetDlgItem(hDlg, IDC_DESCFIXED), GetFont(FONT_EDIT), FALSE); } // Can this player edit this object's description? if (info->flags & DF_EDITABLE) Edit_SetReadOnly(hEdit, FALSE); Edit_LimitText(hEdit, MAX_DESCRIPTION); if (!(info->flags & (DF_EDITABLE | DF_INSCRIBED)) && !str) { GetWindowRect(hFixed, &fixed_rect); GetWindowRect(hEdit, &edit_rect); UnionRect(&fixed_rect, &fixed_rect, &edit_rect); ScreenToClient(hDlg, (LPPOINT)(&fixed_rect)); ScreenToClient(hDlg, (LPPOINT)(&fixed_rect)+1); MoveWindow(hFixed, fixed_rect.left, fixed_rect.top, fixed_rect.right - fixed_rect.left, fixed_rect.bottom - fixed_rect.top, FALSE); ShowWindow(hEdit, SW_HIDE); } // Resize and move dialog controls GetWindowRect(hDlg, &dlg_rect); if (GetWindowLong(hEdit, GWL_STYLE) & WS_VISIBLE) { ShowWindow(hEdit, SW_HIDE); ResizeEditToFitText(hFixed, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); ShowWindow(hEdit, SW_SHOW); } else { ResizeEditToFitText(hFixed, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); } if (GetWindowLong(hEdit, GWL_STYLE) & WS_VISIBLE) { GetWindowRect(hFixed, &fixed_rect); GetWindowRect(hEdit, &edit_rect); height = fixed_rect.bottom-edit_rect.top; ScreenToClient(hDlg, (LPPOINT)(&edit_rect)); ScreenToClient(hDlg, (LPPOINT)(&edit_rect)+1); ShowWindow(hFixed, SW_HIDE); OffsetRect(&edit_rect, 0, height); MoveWindow(hEdit, edit_rect.left, edit_rect.top, edit_rect.right - edit_rect.left, edit_rect.bottom - edit_rect.top, FALSE); GetWindowRect(hDlg, &dlg_rect); ResizeEditToFitText(hEdit, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); ShowWindow(hFixed, SW_SHOW); } CenterWindow(hDlg, GetParent(hDlg)); // Show URL, if appropriate if (info->url != NULL) { hURL = GetDlgItem(hDlg, IDC_URL); SetWindowText(hURL, info->url); SetWindowFont(hURL, GetFont(FONT_EDIT), FALSE); if (info->flags & DF_EDITABLE) Edit_SetReadOnly(hURL, FALSE); Edit_LimitText(hURL, MAX_URL); } // Show appropriate buttons if (!(desc_flags & DESC_GET)) DestroyWindow(GetDlgItem(hDlg, IDC_GET)); if (!(desc_flags & DESC_DROP)) DestroyWindow(GetDlgItem(hDlg, IDC_DROP)); if (!(desc_flags & DESC_USE)) DestroyWindow(GetDlgItem(hDlg, IDC_USE)); if (!(desc_flags & DESC_UNUSE)) DestroyWindow(GetDlgItem(hDlg, IDC_UNUSE)); if (!(desc_flags & DESC_INSIDE)) DestroyWindow(GetDlgItem(hDlg, IDC_INSIDE)); if (!(desc_flags & DESC_ACTIVATE)) DestroyWindow(GetDlgItem(hDlg, IDC_ACTIVATE)); if (!(desc_flags & DESC_APPLY)) DestroyWindow(GetDlgItem(hDlg, IDC_APPLY)); SetLookPageButtons(hDlg, info); #if 0 if (info->numPages < 2) { HWND hwnd = GetDlgItem(hDlg,IDC_NEXT); if (hwnd) DestroyWindow(GetDlgItem(hDlg, IDC_NEXT)); hwnd = GetDlgItem(hDlg,IDC_PREV); if (hwnd) DestroyWindow(GetDlgItem(hDlg, IDC_PREV)); } else { HWND hwnd = GetDlgItem(hDlg,IDC_PREV); if (hwnd) EnableWindow(hwnd,FALSE); } #endif SetFocus(hwndOK); hDescDialog = hDlg; changed = False; return FALSE; case WM_PAINT: InvalidateRect(hwndBitmap, NULL, TRUE); UpdateWindow(hwndBitmap); /* fall through */ case BK_ANIMATE: /* Draw object's bitmap */ hdc = GetDC(hwndBitmap); GetClientRect(hwndBitmap, &dlg_rect); RectToArea(&dlg_rect, &area); DrawStretchedObjectGroup(hdc, info->obj, info->obj->animate->group, &area, GetSysColorBrush(COLOR_3DFACE)); ReleaseDC(hwndBitmap, hdc); break; HANDLE_MSG(hDlg, WM_CTLCOLOREDIT, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORLISTBOX, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORSTATIC, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORDLG, DialogCtlColor); case WM_DESTROY: hDescDialog = NULL; return TRUE; case WM_DRAWITEM: // Draw player name in color that reflects murderer status lpdis = (DRAWITEMSTRUCT *) lParam; switch (lpdis->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: SelectPalette(lpdis->hDC, hPal, FALSE); hFont = info->hFontTitle; SelectObject(lpdis->hDC, hFont); SetBkMode(lpdis->hDC, TRANSPARENT); str = LookupNameRsc(info->obj->name_res); SetTextColor(lpdis->hDC, NAME_COLOR_NORMAL_BG); DrawText(lpdis->hDC, str, strlen(str), &lpdis->rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX); OffsetRect(&lpdis->rcItem, -1, -1); SetTextColor(lpdis->hDC, GetPlayerNameColor(info->obj, info->name)); DrawText(lpdis->hDC, str, strlen(str), &lpdis->rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX); break; } return TRUE; case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_PREV: if (info->currentPage > 0) info->currentPage--; GetPageText(descriptionBuffer,info); SetLookPageButtons(hDlg, info); Edit_SetText(GetDlgItem(hDlg, IDC_DESCBOX), descriptionBuffer); #if 0 EnableWindow(GetDlgItem(hDlg,IDC_PREV),info->currentPage > 0); EnableWindow(GetDlgItem(hDlg,IDC_NEXT),info->currentPage < info->numPages-1); #endif return TRUE; case IDC_NEXT: if (info->currentPage < info->numPages-1) info->currentPage++; GetPageText(descriptionBuffer,info); Edit_SetText(GetDlgItem(hDlg, IDC_DESCBOX), descriptionBuffer); SetLookPageButtons(hDlg, info); #if 0 EnableWindow(GetDlgItem(hDlg,IDC_PREV),info->currentPage > 0); EnableWindow(GetDlgItem(hDlg,IDC_NEXT),info->currentPage < info->numPages-1); #endif return TRUE; case IDC_GET: RequestPickup(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_DROP: // Drop all of number items info->obj->temp_amount = info->obj->amount; RequestDrop(info->obj); EndDialog(hDlg, 0); return TRUE; case IDC_USE: // If player isn't holding the object (i.e. there's a Get button), pick object up first if (IsWindowVisible(GetDlgItem(hDlg, IDC_GET))) RequestPickup(info->obj->id); RequestUse(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_UNUSE: RequestUnuse(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_INSIDE: RequestObjectContents(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_ACTIVATE: RequestActivate(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_APPLY: StartApply(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_DESCBOX: if (GET_WM_COMMAND_CMD(wParam, lParam) != EN_CHANGE) break; changed = True; return TRUE; case IDC_URLBUTTON: hURL = GetDlgItem(hDlg, IDC_URL); Edit_GetText(hURL, url, MAX_URL); WebLaunchBrowser(url); return TRUE; case IDOK: // Send new description if changed if (changed) { desc = (char *) SafeMalloc(MAX_DESCRIPTION + 1); GetDlgItemText(hDlg, IDC_DESCBOX, desc, MAX_DESCRIPTION); RequestChangeDescription(info->obj->id, desc); SafeFree(desc); } // Send new URL if changed if (info->url != NULL) { GetDlgItemText(hDlg, IDC_URL, url, MAX_URL); if (strcmp(url, info->url)) RequestChangeURL(player.id, url); } // FALLTHRU case IDCANCEL: SetWindowFont(GetDlgItem(hDlg,IDC_DESCNAME), GetFont(FONT_TITLES), FALSE); if (info->hFontTitle && info->hFontTitle != GetFont(FONT_TITLES)) DeleteObject(info->hFontTitle); info->hFontTitle = NULL; EndDialog(hDlg, IDOK == GET_WM_COMMAND_ID(wParam, lParam)); return TRUE; } break; } return FALSE; }
void update_screen() { IDirectDrawSurface *dst; RECT dstRect; RECT srcRect; HRESULT hr; POINT pt; // NTS: dx_bitmap.is_valid() is not a valid test because base==canvas==NULL unless surface is locked if (ddsurfaceBMP == NULL) return; // NTS: We must provide a source rect, else Windows XP in 24bpp mode will conveniently choose to render the // right half (where extra padding+junk exist) rather than from the left side. Provide a source rect // to make it 100% clear which part of the surface we want blitted to screen. pt.x = pt.y = 0; ClientToScreen(hwndMain,&pt); GetClientRect(hwndMain,&dstRect); OffsetRect(&dstRect,pt.x,pt.y); srcRect.top = srcRect.left = 0; srcRect.right = dx_bitmap.width; srcRect.bottom = dx_bitmap.height; if (ddsurfaceGDI != NULL) dst = ddsurfaceGDI; else if (ddsurfacePrimary != NULL) dst = ddsurfacePrimary; else dst = NULL; if (dst != NULL) hr = dst->Blt(&dstRect,ddsurfaceBMP,&srcRect,0,NULL); else hr = DD_OK; if (hr == DDERR_SURFACELOST) { fprintf(stderr,"Whoops, the primary surface was lost.\n"); if ((hr=dst->Restore()) != DD_OK) { fprintf(stderr,"Unable to restore surface hr=0x%08lx.\n",hr); unlock_bitmap(); free_bitmap(); free_dx_primary_surface(); init_dx_primary_surface(); RECT rct; GetClientRect(hwndMain,&rct); if (!init_bitmap(rct.right,rct.bottom)) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", (unsigned int)rct.right,(unsigned int)rct.bottom); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint } } else if (hr != DD_OK) { fprintf(stderr,"DirectX blit failed, HR=0x%08lx\n",hr); } }
//------------------------------------------------------ BOOL CRectTracker::TrackHandle( HWND hWnd, const LPPOINT point, int HitTest ) { ATLASSERT(point); if ((HitTest != hitBegin) && (HitTest != hitEnd) && (HitTest != hitMiddle)) return FALSE; if (!IsValidPos()) return FALSE; // set mouse cursor parameters RECT CursorRect; if (IsRectEmpty(&ValidRect)) { GetClientRect(hWnd, &CursorRect); } else { // valid rectangle is not empty if (HitTest == hitMiddle) { RECT BeginRect = ValidRect; OffsetRect(&BeginRect, point->x, point->y); OffsetRect(&BeginRect, -CurPos.Begin.x, -CurPos.Begin.y); NormalizeRect(&BeginRect); RECT EndRect = ValidRect; OffsetRect(&EndRect, point->x, point->y); OffsetRect(&EndRect, -CurPos.End.x, -CurPos.End.y); NormalizeRect(&EndRect); CursorRect = ValidRect; IntersectRect(&CursorRect, &CursorRect, &BeginRect); IntersectRect(&CursorRect, &CursorRect, &EndRect); } else CursorRect = ValidRect; }; if (IsRectEmpty(&CursorRect)) return FALSE; ClientToScreen(hWnd, (LPPOINT)&CursorRect ); ClientToScreen(hWnd, ((LPPOINT)&CursorRect)+1 ); ClipCursor(&CursorRect); SetCapture(hWnd); // get DC for drawing HDC dc = GetDC(hWnd); // set dc parameters HPEN LinePen = CreatePen( PS_SOLID, LineWidth, CLR_WHITE ); HPEN hOldPen = (HPEN)SelectObject(dc, LinePen); SetROP2(dc, R2_XORPEN ); KLinePos OriginalPos = CurPos; BOOL bCanceled = FALSE; // draw the rectangle for the first time DrawRect(dc, &CurPos.Begin, &CurPos.End); // get messages until capture lost or cancelled/accepted BOOL bExit = FALSE; KLinePos NewPos; while (!bExit) { MSG msg; BOOL b = ::GetMessage(&msg, NULL, 0, 0); ATLASSERT(b); if (GetCapture() != hWnd) break; // exit loop switch (msg.message) { // handle movement/accept messages case WM_LBUTTONUP: case WM_MOUSEMOVE: { NewPos = CurPos; POINT MousePoint = { (int)(short)LOWORD(msg.lParam), (int)(short)HIWORD(msg.lParam) }; switch (HitTest) { case hitBegin: NewPos.Begin = MousePoint; break; case hitEnd: NewPos.End = MousePoint; break; case hitMiddle: NewPos.Begin.x = OriginalPos.Begin.x + (MousePoint.x-point->x); NewPos.Begin.y = OriginalPos.Begin.y + (MousePoint.y-point->y); NewPos.End.x = OriginalPos.End.x + (MousePoint.x-point->x); NewPos.End.y = OriginalPos.End.y + (MousePoint.y-point->y); break; }; // redraw the line if ((NewPos.Begin.x != CurPos.Begin.x) || (NewPos.Begin.y != CurPos.Begin.y) || (NewPos.End.x != CurPos.End.x) || (NewPos.End.y != CurPos.End.y)) { // draw new rectangle DrawRect(dc, &NewPos.Begin, &NewPos.End); // erase old rectangle DrawRect(dc, &CurPos.Begin, &CurPos.End); }; if (IsValidPos(NewPos)) CurPos = NewPos; if (msg.message == WM_LBUTTONUP) bExit = TRUE; }; break; // handle cancel messages case WM_KEYDOWN: if (msg.wParam == VK_ESCAPE) { bCanceled = TRUE; bExit = TRUE; }; break; case WM_RBUTTONDOWN: bCanceled = TRUE; bExit = TRUE; break; // just dispatch rest of the messages default: DispatchMessage(&msg); break; } }; ClipCursor(NULL); ReleaseCapture(); if (bCanceled) CurPos = OriginalPos; SelectObject(dc, hOldPen); DeleteObject(LinePen); ReleaseDC(hWnd, dc); return !bCanceled; };
static void setdisplaymode(int i) { HRESULT rc; RECT orig_rect; SetRect(&orig_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc); if (modes[i].dwFlags & DDSD_PIXELFORMAT) { if (modes[i].ddpfPixelFormat.dwFlags & DDPF_RGB) { rc = IDirectDraw_SetDisplayMode(lpDD, modes[i].dwWidth, modes[i].dwHeight, U1(modes[i].ddpfPixelFormat).dwRGBBitCount); ok(DD_OK==rc || DDERR_UNSUPPORTED==rc,"SetDisplayMode returned: %x\n",rc); if (rc == DD_OK) { RECT r, scrn, test, virt; SetRect(&virt, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)); OffsetRect(&virt, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN)); SetRect(&scrn, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); trace("Mode (%dx%d) [%dx%d] (%d %d)x(%d %d)\n", modes[i].dwWidth, modes[i].dwHeight, scrn.right, scrn.bottom, virt.left, virt.top, virt.right, virt.bottom); if (!EqualRect(&scrn, &orig_rect)) { HRESULT rect_result; /* Check that the client rect was resized */ rc = GetClientRect(hwnd, &test); ok(rc!=0, "GetClientRect returned %x\n", rc); rc = EqualRect(&scrn, &test); todo_wine ok(rc!=0, "Fullscreen window has wrong size\n"); /* Check that switching to normal cooperative level does not restore the display mode */ rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_NORMAL); ok(rc==DD_OK, "SetCooperativeLevel returned %x\n", rc); SetRect(&test, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); rect_result = EqualRect(&scrn, &test); ok(rect_result!=0, "Setting cooperative level to DDSCL_NORMAL changed the display mode\n"); /* Go back to fullscreen */ rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n",rc); /* If the display mode was changed, set the correct mode to avoid irrelevant failures */ if (rect_result == 0) { rc = IDirectDraw_SetDisplayMode(lpDD, modes[i].dwWidth, modes[i].dwHeight, U1(modes[i].ddpfPixelFormat).dwRGBBitCount); ok(DD_OK==rc, "SetDisplayMode returned: %x\n",rc); } } ok(GetClipCursor(&r), "GetClipCursor() failed\n"); /* ddraw sets clip rect here to the screen size, even for multiple monitors */ ok(EqualRect(&r, &scrn), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom); ok(ClipCursor(NULL), "ClipCursor() failed\n"); ok(GetClipCursor(&r), "GetClipCursor() failed\n"); ok(EqualRect(&r, &virt), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom); rc = IDirectDraw_RestoreDisplayMode(lpDD); ok(DD_OK==rc,"RestoreDisplayMode returned: %x\n",rc); } } } }
long CALLBACK EXPORT ConsoleFunc(HWND hwnd,unsigned message,WPARAM wParam, LPARAM lParam) { CONSOLE *con; PAINTSTRUCT ps; RECT rect; switch (message) { case WM_CHAR: if ((con=Hwnd2Console(hwnd))!=NULL) { /* store in a key queue */ if ((con->keyq_end+1)%KEYQUEUE_SIZE==con->keyq_start) { MessageBeep(MB_OK); break; } /* if */ con->keyqueue[con->keyq_end]=(short)wParam; con->keyq_end=(con->keyq_end+1)%KEYQUEUE_SIZE; } /* if */ break; case WM_CREATE: /* The "hwnd" member of the CONSOLE structure has not yet been set, which * means that Hwnd2Console() cannot work on the real "hwnd". There should * at every instant be only one CONSOLE structure with a NULL handle, * however. */ if ((con=Hwnd2Console(NULL))!=NULL) { con->hwnd=hwnd; SetConsoleFont(con,con->cheight); GetWindowRect(hwnd, &rect); SetRect(&rect,rect.left,rect.top, rect.left+con->cwidth*con->columns, rect.top+con->cheight*con->winlines); AdjustWindowRect(&rect,GetWindowLong(hwnd,GWL_STYLE),FALSE); if (con->winlines<con->lines) rect.right+=GetSystemMetrics(SM_CXVSCROLL); ClampToScreen(&rect); SetWindowPos(hwnd,NULL,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top, SWP_NOZORDER); } /* if */ break; case WM_DESTROY: if ((con=Hwnd2Console(hwnd))!=NULL) DoDeleteConsole(con); break; case WM_GETMINMAXINFO: if ((con=Hwnd2Console(hwnd))!=NULL) { MINMAXINFO FAR *lpmmi=(MINMAXINFO FAR*)lParam; int rx,ry,hsize,vsize; GetClientRect(hwnd,&rect); rx= (rect.right < con->columns*con->cwidth) ? con->columns*con->cwidth-rect.right : 0; ry= (rect.bottom < con->lines*con->cheight) ? con->lines*con->cheight-rect.bottom : 0; hsize= (ry>0) ? GetSystemMetrics(SM_CXVSCROLL) : 0; vsize= (rx>0) ? GetSystemMetrics(SM_CYHSCROLL) : 0; SetRect(&rect,0,0,con->cwidth*con->columns+hsize,con->cheight*con->lines+vsize); AdjustWindowRect(&rect,GetWindowLong(hwnd,GWL_STYLE),FALSE); lpmmi->ptMaxTrackSize.x=rect.right-rect.left; lpmmi->ptMaxTrackSize.y=rect.bottom-rect.top; lpmmi->ptMaxSize=lpmmi->ptMaxTrackSize; } /* if */ break; case WM_SYSKEYDOWN: case WM_KEYDOWN: if ((con=Hwnd2Console(hwnd))!=NULL) { TCHAR str[20]; int i; str[0]=__T('\0'); switch (LOWORD(wParam)) { case VK_F1: case VK_F2: case VK_F3: case VK_F4: case VK_F5: case VK_F6: case VK_F7: case VK_F8: case VK_F9: case VK_F10: case VK_F11: case VK_F12: if (LOWORD(wParam)<=VK_F5) _stprintf(str,__T("\033[%d~\n"),LOWORD(wParam)-VK_F1+11); else if (LOWORD(wParam)==VK_F10) _stprintf(str,__T("\033[%d~\n"),LOWORD(wParam)-VK_F6+17); else _stprintf(str,__T("\033[%d~\n"),LOWORD(wParam)-VK_F11+23); break; case VK_ADD: case VK_SUBTRACT: /* check Ctrl key */ if ((GetKeyState(VK_CONTROL) & 0x8000)!=0) { POINT pt; int newheight=con->cheight; int oldheight=newheight; int incr= (LOWORD(wParam)==VK_SUBTRACT) ? -1 : 1; do { newheight+=incr; /* make a new font, re-create a caret and redraw everything */ SetConsoleFont(con,newheight); } while (newheight>5 && (oldheight==con->cheight || con->hfont==NULL)); if (con->hfont==NULL) /* reset to original on failure */ SetConsoleFont(con,oldheight); GetClientRect(hwnd,&rect); DestroyCaret(); CreateCaret(hwnd,NULL,con->cwidth,2); RefreshCaretPos(con); /* redraw the window */ InvalidateRect(hwnd,NULL,TRUE); /* resize the window */ SetRect(&rect,0,0,con->cwidth*con->columns,con->cheight*con->winlines); AdjustWindowRect(&rect,GetWindowLong(hwnd,GWL_STYLE),FALSE); pt.x=pt.y=0; ClientToScreen(hwnd,&pt); OffsetRect(&rect,pt.x,pt.y); ClampToScreen(&rect); SetWindowPos(hwnd,NULL,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top, SWP_NOZORDER); } /* if */ break; case VK_UP: _tcscpy(str,__T("\033[A")); break; case VK_DOWN: _tcscpy(str,__T("\033[B")); break; case VK_RIGHT: _tcscpy(str,__T("\033[C")); break; case VK_LEFT: _tcscpy(str,__T("\033[D")); break; case VK_HOME: _tcscpy(str,__T("\033[1~")); break; case VK_END: _tcscpy(str,__T("\033[4~")); break; case VK_INSERT: _tcscpy(str,__T("\033[2~")); break; case VK_DELETE: _tcscpy(str,__T("\033[3~")); break; case VK_PRIOR: /* PageUp */ _tcscpy(str,__T("\033[5~")); break; case VK_NEXT: /* PageDown */ _tcscpy(str,__T("\033[6~")); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } /* switch */ for (i=0; str[i]!=__T('\0'); i++) { if ((con->keyq_end+1)%KEYQUEUE_SIZE!=con->keyq_start) { con->keyqueue[con->keyq_end]=(short)str[i]; con->keyq_end=(con->keyq_end+1)%KEYQUEUE_SIZE; } /* if */ } /* for */ } /* if */ break; case WM_KILLFOCUS: HideCaret(hwnd); DestroyCaret(); break; case WM_SETFOCUS: if ((con=Hwnd2Console(hwnd))!=NULL) { CreateCaret(hwnd,NULL,con->cwidth,2); RefreshCaretPos(con); ShowCaret(hwnd); } /* if */ break; case WM_LBUTTONDOWN: SetFocus(hwnd); break; case WM_PAINT: HideCaret(hwnd); BeginPaint(hwnd, &ps); if ((con=Hwnd2Console(hwnd))!=NULL && con->buffer!=NULL) { TCHAR *string; string=malloc(con->columns*sizeof(TCHAR)); if (string!=NULL) { int l,c,bpos,start; TCHAR attr; HFONT hfontOrg; int scrollx=GetScrollPos(hwnd,SB_HORZ); int scrolly=GetScrollPos(hwnd,SB_VERT); GetClientRect(hwnd,&rect); hfontOrg=SelectObject(ps.hdc,con->hfont); SetBkMode(ps.hdc,OPAQUE); for (l=0; l<con->lines; l++) { bpos=l*con->columns*2; c=0; while (c<con->columns) { /* find stretches with the same attribute */ attr=con->buffer[bpos+1]; start=c; while (c<con->columns && con->buffer[bpos+1]==attr) { assert(c-start>=0); assert(c-start<con->columns); string[c-start]=con->buffer[bpos]; c++; bpos+=2; } /* if */ SetTextAttribute(ps.hdc,attr); TextOut(ps.hdc,start*con->cwidth-scrollx,l*con->cheight-scrolly,string,c-start); } /* while */ } /* for */ SelectObject(ps.hdc,hfontOrg); free(string); } /* if */ } /* if */ EndPaint(hwnd, &ps); ShowCaret(hwnd); break; case WM_SIZE: if ((con=Hwnd2Console(hwnd))!=NULL) { int rx,ry; /* add/remove/recalculate scroll bars */ GetClientRect(hwnd,&rect); rx= (rect.right < con->columns*con->cwidth) ? con->columns*con->cwidth-rect.right : 0; ry= (rect.bottom < con->lines*con->cheight) ? con->lines*con->cheight-rect.bottom : 0; /* adjust scrolling position, if necessary */ if (GetScrollPos(hwnd,SB_HORZ)>=rx) { SetScrollPos(hwnd,SB_HORZ,rx,FALSE); InvalidateRect(hwnd,NULL,FALSE); } /* if */ if (GetScrollPos(hwnd,SB_VERT)>=ry) { SetScrollPos(hwnd,SB_VERT,ry,FALSE); InvalidateRect(hwnd,NULL,FALSE); } /* if */ SetScrollRange(hwnd,SB_HORZ,0,rx,TRUE); SetScrollRange(hwnd,SB_VERT,0,ry,TRUE); } /* if */ break; case WM_HSCROLL: if ((con=Hwnd2Console(hwnd))!=NULL) { int scrollx=GetScrollPos(hwnd,SB_HORZ); int oldpos=scrollx; int min,max; GetScrollRange(hwnd,SB_HORZ,&min,&max); switch (LOWORD(wParam)) { case SB_TOP: scrollx=min; break; case SB_BOTTOM: scrollx=max; break; case SB_LINELEFT: scrollx=(scrollx>min) ? scrollx-1 : min; break; case SB_LINERIGHT: scrollx=(scrollx<max) ? scrollx+1 : max; break; case SB_PAGELEFT: scrollx=(scrollx>min) ? scrollx-50 : min; break; case SB_PAGERIGHT: scrollx=(scrollx<max) ? scrollx+50 : max; break; case SB_THUMBTRACK: scrollx=(int)HIWORD(wParam); break; } /* switch */ if (oldpos!=scrollx) { SetScrollPos(hwnd,SB_HORZ,scrollx,TRUE); InvalidateRect(hwnd,NULL,FALSE); RefreshCaretPos(con); } /* if */ } /* if */ break; case WM_VSCROLL: if ((con=Hwnd2Console(hwnd))!=NULL) { int scrolly=GetScrollPos(hwnd,SB_VERT); int oldpos=scrolly; int min,max; GetScrollRange(hwnd,SB_VERT,&min,&max); switch (LOWORD(wParam)) { case SB_TOP: scrolly=min; break; case SB_BOTTOM: scrolly=max; break; case SB_LINELEFT: scrolly=(scrolly>min) ? scrolly-1 : min; break; case SB_LINERIGHT: scrolly=(scrolly<max) ? scrolly+1 : max; break; case SB_PAGELEFT: scrolly=(scrolly>min) ? scrolly-50 : min; break; case SB_PAGERIGHT: scrolly=(scrolly<max) ? scrolly+50 : max; break; case SB_THUMBTRACK: scrolly=(int)HIWORD(wParam); break; } /* switch */ if (oldpos!=scrolly) { SetScrollPos(hwnd,SB_VERT,scrolly,TRUE); InvalidateRect(hwnd,NULL,FALSE); RefreshCaretPos(con); } /* if */ } /* if */ break; default: return DefWindowProc(hwnd,message,wParam,lParam); } /* switch */ return 0L; }
//------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { if(m_specific->m_sys_format == pix_format_undefined) { return false; } m_window_flags = flags; // application EventTypeSpec eventType; EventHandlerUPP handlerUPP; eventType.eventClass = kEventClassApplication; eventType.eventKind = kEventAppQuit; handlerUPP = NewEventHandlerUPP(DoAppQuit); InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil); eventType.eventClass = kEventClassMouse; eventType.eventKind = kEventMouseDown; handlerUPP = NewEventHandlerUPP(DoMouseDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseUp; handlerUPP = NewEventHandlerUPP(DoMouseUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseDragged; handlerUPP = NewEventHandlerUPP(DoMouseDragged); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventClass = kEventClassKeyboard; eventType.eventKind = kEventRawKeyDown; handlerUPP = NewEventHandlerUPP(DoKeyDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyUp; handlerUPP = NewEventHandlerUPP(DoKeyUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyRepeat; handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down' InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); WindowAttributes windowAttrs; Rect bounds; // window windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute; SetRect (&bounds, 0, 0, width, height); OffsetRect (&bounds, 100, 100); CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window); if(m_specific->m_window == nil) { return false; } // I assume the text is ASCII. // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need. SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil)); eventType.eventClass = kEventClassWindow; eventType.eventKind = kEventWindowClose; handlerUPP = NewEventHandlerUPP(DoWindowClose); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); eventType.eventKind = kEventWindowDrawContent; handlerUPP = NewEventHandlerUPP(DoWindowDrawContent); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); // Periodic task // Instead of an idle function I use the Carbon event timer. // You may decide to change the wait value which is currently 50 milliseconds. EventLoopRef mainLoop; EventLoopTimerUPP timerUPP; EventLoopTimerRef theTimer; mainLoop = GetMainEventLoop(); timerUPP = NewEventLoopTimerUPP (DoPeriodicTask); InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer); m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; on_init(); on_resize(width, height); m_specific->m_redraw_flag = true; ShowWindow (m_specific->m_window); SetPortWindowPort (m_specific->m_window); return true; }
static void test_GetRandomRgn(void) { HWND hwnd = CreateWindowExA(0,"BUTTON","test",WS_VISIBLE|WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0); HDC hdc; HRGN hrgn = CreateRectRgn(0, 0, 0, 0); int ret; RECT rc, rc2; RECT ret_rc, window_rc; ok( hwnd != 0, "CreateWindow failed\n" ); SetRect(&window_rc, 400, 300, 500, 400); SetWindowPos(hwnd, HWND_TOPMOST, window_rc.left, window_rc.top, window_rc.right - window_rc.left, window_rc.bottom - window_rc.top, 0 ); hdc = GetDC(hwnd); ret = GetRandomRgn(hdc, hrgn, 1); ok(ret == 0, "GetRandomRgn rets %d\n", ret); ret = GetRandomRgn(hdc, hrgn, 2); ok(ret == 0, "GetRandomRgn rets %d\n", ret); ret = GetRandomRgn(hdc, hrgn, 3); ok(ret == 0, "GetRandomRgn rets %d\n", ret); /* Set a clip region */ SetRect(&rc, 20, 20, 80, 80); IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); ret = GetRandomRgn(hdc, hrgn, 1); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); ret = GetRandomRgn(hdc, hrgn, 2); ok(ret == 0, "GetRandomRgn rets %d\n", ret); ret = GetRandomRgn(hdc, hrgn, 3); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); /* Move the clip to the meta and clear the clip */ SetMetaRgn(hdc); ret = GetRandomRgn(hdc, hrgn, 1); ok(ret == 0, "GetRandomRgn rets %d\n", ret); ret = GetRandomRgn(hdc, hrgn, 2); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); ret = GetRandomRgn(hdc, hrgn, 3); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); /* Set a new clip (still got the meta) */ SetRect(&rc2, 10, 30, 70, 90); IntersectClipRect(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom); ret = GetRandomRgn(hdc, hrgn, 1); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); ret = GetRandomRgn(hdc, hrgn, 2); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); IntersectRect(&rc2, &rc, &rc2); ret = GetRandomRgn(hdc, hrgn, 3); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); ret = GetRandomRgn(hdc, hrgn, SYSRGN); ok(ret != 0, "GetRandomRgn rets %d\n", ret); GetRgnBox(hrgn, &ret_rc); if(GetVersion() & 0x80000000) OffsetRect(&window_rc, -window_rc.left, -window_rc.top); /* the window may be partially obscured so the region may be smaller */ IntersectRect( &window_rc, &ret_rc, &ret_rc ); ok(EqualRect(&window_rc, &ret_rc) || broken(IsRectEmpty(&ret_rc)), /* win95 */ "GetRandomRgn %d,%d - %d,%d\n", ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); DeleteObject(hrgn); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); }
/** * This is the message procedure for my nice looking message box * * @param hDlg - window handle * @param uMsg - message to handle * @param wParam - message specific parameter * @param lParam - message specific parameter * * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL **/ static INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int retOk = IDOK; static int retAll = IDALL; static int retNon = IDNONE; static int retCancel = IDCANCEL; switch (uMsg) { case WM_INITDIALOG: { LPMSGBOX pMsgBox = (LPMSGBOX)lParam; if (PtrIsValid(pMsgBox)) { int icoWidth = 0; int InfoBarHeight = 0; HFONT hNormalFont; hNormalFont = (HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0); if (pMsgBox->uType & MB_INFOBAR) { LOGFONT lf; // set bold font for name in description area GetObject(hNormalFont, sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hNormalFont = CreateFontIndirect(&lf); // set infobar's textfont SendDlgItemMessage(hDlg, TXT_NAME, WM_SETFONT, (WPARAM)hNormalFont, 0); // set infobar's logo icon SendDlgItemMessage(hDlg, ICO_DLGLOGO, STM_SETIMAGE, IMAGE_ICON, (pMsgBox->hiLogo ? (LPARAM)pMsgBox->hiLogo : (LPARAM)IcoLib_GetIcon(ICO_DLG_DETAILS,TRUE))); // enable headerbar ShowWindow(GetDlgItem(hDlg, TXT_NAME), SW_SHOW); ShowWindow(GetDlgItem(hDlg, ICO_DLGLOGO), SW_SHOW); } else { RECT rc; GetClientRect(GetDlgItem(hDlg, TXT_NAME), &rc); InfoBarHeight = rc.bottom; if (pMsgBox->hiLogo) SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)pMsgBox->hiLogo); } // draw the desired status icon HICON hIcon = MsgLoadIcon(pMsgBox); if (hIcon) SendDlgItemMessage(hDlg, ICO_MSGDLG, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); else { RECT ws; GetWindowRect(GetDlgItem(hDlg, ICO_MSGDLG), &ws); icoWidth = ws.right - ws.left; ShowWindow(GetDlgItem(hDlg, ICO_MSGDLG), SW_HIDE); } // resize the messagebox and reorganize the buttons if (HDC hDC = GetDC(hDlg)) { POINT mpt = { 0, 0 }; RECT ws = { 0, 0, 0, 0 }; int txtWidth=0, txtHeight=0, needX, needY; RECT rcDlg; SIZE ts; LPTSTR h, rs; SelectObject(hDC, hNormalFont); // get message text width and height if(pMsgBox->ptszMsg) for (rs=h=pMsgBox->ptszMsg; ; ++h) { if (*h=='\n' || !*h) { GetTextExtentPoint32(hDC, rs, h-rs, &ts); if (ts.cx > txtWidth) txtWidth = ts.cx; txtHeight += ts.cy; if (!*h) break; rs = h+1; } } // increase width if info text requires more if((pMsgBox->uType&MB_INFOBAR) && pMsgBox->ptszInfoText && *pMsgBox->ptszInfoText){ //int multiline = 0; RECT rcico; GetClientRect(GetDlgItem(hDlg,ICO_DLGLOGO), &rcico); rcico.right = rcico.right*100/66; // padding for(rs=h=pMsgBox->ptszInfoText; ; ++h) { if (*h=='\n' || !*h) { GetTextExtentPoint32(hDC, rs, h-rs, &ts); ts.cx += rcico.right; if (ts.cx > txtWidth) txtWidth = ts.cx; if (!*h) break; rs = h+1; //++multiline; } } /* used by SendSS, disabled for UserInfoEx for now if(!multiline) SetWindowLongPtr(GetDlgItem(hDlg,TXT_NAME), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg,TXT_NAME), GWL_STYLE)|SS_CENTERIMAGE); */ } ReleaseDC(hDlg, hDC); // calc new dialog size GetWindowRect(hDlg, &rcDlg); GetWindowRect(GetDlgItem(hDlg, TXT_MESSAGE), &ws); needX = txtWidth - (ws.right - ws.left) - icoWidth; needY = max(0, txtHeight - (ws.bottom - ws.top) + 5); rcDlg.left -= needX/2; rcDlg.right += needX/2; rcDlg.top -= (needY-InfoBarHeight)/2; rcDlg.bottom += (needY-InfoBarHeight)/2; // resize dialog window MoveWindow(hDlg, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, FALSE); ClientToScreen(hDlg, &mpt); MoveCtrl(hDlg, STATIC_WHITERECT, -mpt.x, -mpt.y, needX, needY - InfoBarHeight); MoveCtrl(hDlg, TXT_NAME, -mpt.x, -mpt.y, needX, 0); MoveCtrl(hDlg, ICO_DLGLOGO, -mpt.x + needX, -mpt.y, 0, 0); MoveCtrl(hDlg, ICO_MSGDLG, -mpt.x, -mpt.y - InfoBarHeight, 0, 0); MoveCtrl(hDlg, TXT_MESSAGE, -mpt.x - icoWidth, -mpt.y - InfoBarHeight, needX, needY); MoveCtrl(hDlg, STATIC_LINE2, -mpt.x, -mpt.y + needY - InfoBarHeight, needX, 0); // // Do pushbutton positioning // RECT rcOk, rcAll, rcNone, rcCancel; // get button rectangles GetWindowRect(GetDlgItem(hDlg, IDOK), &rcOk); OffsetRect(&rcOk, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDALL), &rcAll); OffsetRect(&rcAll, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDNONE), &rcNone); OffsetRect(&rcNone, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcCancel); OffsetRect(&rcCancel, -mpt.x, -mpt.y + needY - InfoBarHeight); LONG okWidth = rcOk.right - rcOk.left; LONG allWidth = rcAll.right - rcAll.left; LONG noneWidth = rcNone.right - rcNone.left; LONG caWidth = rcCancel.right - rcCancel.left; LONG dlgMid = (rcDlg.right - rcDlg.left) / 2; // load button configuration switch (MB_TYPE(pMsgBox->uType)) { case MB_OK: rcOk.left = dlgMid - (okWidth / 2); rcOk.right = rcOk.left + okWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); break; case MB_OKCANCEL: retOk = IDRETRY; SetDlgItemText(hDlg, IDOK, LPGENT("OK")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_RETRYCANCEL: retOk = IDRETRY; SetDlgItemText(hDlg, IDOK, LPGENT("Retry")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESNO: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retCancel = IDNO; SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_ABORTRETRYIGNORE: retOk = IDABORT; SetDlgItemText(hDlg, IDOK, LPGENT("Abort")); retAll = IDABORT; SetDlgItemText(hDlg, IDALL, LPGENT("Retry")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Ignore")); rcAll.left = dlgMid - (allWidth / 2); rcAll.right = rcAll.left + allWidth; rcOk.left = rcAll.left - okWidth - 5; rcOk.right = rcOk.left + okWidth; rcCancel.left = rcAll.right + 5; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESNOCANCEL: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retAll = IDNO; SetDlgItemText(hDlg, IDALL, LPGENT("No")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcAll.left = dlgMid - (allWidth / 2); rcAll.right = rcAll.left + allWidth; rcOk.left = rcAll.left - okWidth - 5; rcOk.right = rcOk.left + okWidth; rcCancel.left = rcAll.right + 5; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESALLNO: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retAll = IDALL; SetDlgItemText(hDlg, IDALL, LPGENT("All")); //retNon = IDNONE; SetDlgItemText(hDlg, IDNONE, LPGENT("None")); retCancel = IDNO; SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); rcCancel.right = rcDlg.right - rcDlg.left - 10; rcCancel.left = rcCancel.right - caWidth; rcNone.right = rcCancel.left - 5; rcNone.left = rcNone.right - noneWidth; rcAll.right = rcNone.left - 5; rcAll.left = rcAll.right - allWidth; rcOk.right = rcAll.left - 5; rcOk.left = rcOk.right - okWidth; // show buttons ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDNONE), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; default: rcOk.left = dlgMid - (okWidth / 2); rcOk.right = rcOk.left + okWidth; } MoveWindow(GetDlgItem(hDlg, IDOK), rcOk.left, rcOk.top, rcOk.right - rcOk.left, rcOk.bottom - rcOk.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDALL), rcAll.left, rcAll.top, rcAll.right - rcAll.left, rcAll.bottom - rcAll.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDNONE), rcNone.left, rcNone.top, rcNone.right - rcNone.left, rcNone.bottom - rcNone.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDCANCEL), rcCancel.left, rcCancel.top, rcCancel.right - rcCancel.left, rcCancel.bottom - rcCancel.top, FALSE); } // set text's SetWindowText(hDlg, pMsgBox->ptszTitle); SetDlgItemText(hDlg, TXT_NAME, pMsgBox->ptszInfoText); SetDlgItemText(hDlg, TXT_MESSAGE, pMsgBox->ptszMsg); TranslateDialogDefault(hDlg); return TRUE; } } break; case WM_CTLCOLORSTATIC: switch (GetWindowLongPtr((HWND)lParam, GWLP_ID)) { case STATIC_WHITERECT: case ICO_DLGLOGO: case ICO_MSGDLG: case TXT_MESSAGE: case TXT_NAME: SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT)); return GetSysColor(COLOR_WINDOW); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hDlg, retOk); break; case IDCANCEL: EndDialog(hDlg, retCancel); break; case IDALL: EndDialog(hDlg, retAll); break; case IDNONE: EndDialog(hDlg, retNon); } break; case WM_DESTROY: DeleteObject((HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0)); break; } return FALSE; }