我想更改应用程序中标题栏的颜色,就像我在 Skype Preview 等程序中看到的那样。我在互联网上只找到了一个解决方案(WM_NCPAINT),这似乎需要我绘制一个完全自定义的标题栏,当我只想更改背景颜色时,这当然不理想。有人知道更好的解决方案吗?有人建议 Hook GetSysColor,但从未使用索引 2 (COLOR_ACTIVECAPTION) 调用它,因此颜色是从其他地方检索的。
当前标题栏:
(来源:pbrd.co)
最终目标:
最佳答案
我要说的第一件事是:你被警告了! 这是一项非常费力的任务。阅读 Wine 源代码( native win32 功能的 linux 实现)花了很多时间来轻松阅读。
看到这个问题让我想起了我为达到相同结果所做的努力的“喜欢”(读作:令人恼火!)。这个过程有点复杂,并且比简单地绘制标题栏给你带来了更多的责任。 (我已经包含了大约 500 行代码)
除其他外,您还需要处理窗口激活/停用、大小调整、NC 区域按钮、应用程序图标和标题文本。
使用我未包含的其他文件中的一些(绘图)实用程序功能,实现了以下目标:
这两个都是对这个对话框的修改:
借助这些(颜色键控)图像:
和一些拉伸(stretch)/绘图(图像分为 9 block )
我在重新查看此代码时注意到,客户区过度绘制了边框。我想,因为我没有正确调整它以响应 WM_NCCALCSIZE 消息。我还使用了另一个确实有 8 像素宽边框的图像,而不是这两个显示的 14 像素。 (您可以看到响应我提到的消息的注释掉的代码)
首先,我们将标准对话框的 WindowProc 子类化。在这个子类处理程序中,我们告诉桌面窗口管理器禁用窗口的合成,我们设置一个分层窗口(这就是黑色的半透明窗口),最后,我们自己进行非客户端绘图以响应WM_NCPAINT 消息。
我还要指出,由于我早已忘记的原因,我对代码的功能并不是特别满意。
话虽如此,这里有一些代码可以让你深入了解:
#define _WIN32_WINNT 0x0501
#define UNICODE 1
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#include "../graphics/graphics.h"
#include <dwmapi.h>
using namespace Gdiplus;
HINSTANCE hInst;
LRESULT CALLBACK DlgSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT onNcPaint(HWND hwnd, WPARAM wParam, LPARAM lParam);
HBITMAP frameImg, frameRedImg, frameOrigImg;
int frameIndex = 0;
//HRESULT DwmEnableComposition(UINT uCompositionAction);
typedef HRESULT (WINAPI *pFnDwmEnableComposition)(UINT uCompAction);
typedef HRESULT (WINAPI *pFnDwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
#define WM_DMWNCRENDERINGCHANGED 0x31F
// wParam = 1 (fRenderingEnabled = true)
// wParam = 0 (fRenderingEnabled = false)
HRESULT EnableNcDwm(HWND hwnd, bool enable)
{
HMODULE dwmMod = LoadLibrary(L"dwmapi.dll");
if (dwmMod)
{
pFnDwmSetWindowAttribute DwmSetWindowAttribute;
DwmSetWindowAttribute = (pFnDwmSetWindowAttribute)GetProcAddress(dwmMod, "DwmSetWindowAttribute");
HRESULT hr = S_OK;
DWMNCRENDERINGPOLICY ncrp;
if (enable)
ncrp = DWMNCRP_ENABLED;
else
ncrp = DWMNCRP_DISABLED;
// Disable non-client area rendering on the window.
hr = DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));
FreeLibrary(dwmMod);
if (SUCCEEDED(hr))
{
return hr;
}
}
return S_FALSE;
}
/*
#define DWM_EC_DISABLECOMPOSITION 0
#define DWM_EC_ENABLECOMPOSITION 1
HRESULT EnableDWM(HWND hwnd, bool enable)
{
HMODULE dwmMod = LoadLibrary(L"dwmapi.dll");
pFnDwmEnableComposition DwmEnableComposition;
DwmEnableComposition = (pFnDwmEnableComposition)GetProcAddress(dwmMod, "DwmEnableComposition");
HRESULT hr = S_OK;
// Disable DWM Composition
if (enable)
hr = DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
else
hr = DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
FreeLibrary(dwmMod);
return hr;
}
*/
BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static bool isSubclassed = false;
switch(uMsg)
{
case WM_DMWNCRENDERINGCHANGED:
{
long dwEx = GetWindowLong(hwndDlg, GWL_EXSTYLE);
dwEx &= ~(WS_EX_LAYERED);
SetWindowLong(hwndDlg, GWL_EXSTYLE, dwEx);
InvalidateRect(hwndDlg, NULL, true);
UpdateWindow(hwndDlg);
MoveAnchorsImmediatelly(hwndDlg);
}
return 0;
// case WM_ERASEBKGND:
// {
// RECT rc;
// GetClientRect(hwndDlg, &rc);
// FillRect((HDC)wParam, &rc, (HBRUSH) COLOR_BACKGROUND);
// return 1;
// }
case WM_INITDIALOG:
{
mSetAnchorMode(GetDlgItem(hwndDlg, IDC_BUTTON1), ANCHOR_CENTER);
}
return TRUE;
case WM_SIZE:
{
//MoveAnchorsImmediatelly(hwndDlg);
DeferAnchorsMove(hwndDlg);
}
return TRUE;
case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}
return TRUE;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BUTTON1:
if (isSubclassed == false)
{
SetWindowSubclass( hwndDlg, DlgSubclassProc, 1, NULL);
EnableNcDwm(hwndDlg, false);
frameIndex++;
frameIndex &= 1; // make sure it can only be in range [0..1]
}
else
{
RemoveWindowSubclass( hwndDlg, DlgSubclassProc, 1);
EnableNcDwm(hwndDlg, true);
}
isSubclassed = !isSubclassed;
// InvalidateRect(hwndDlg, NULL, true);
// UpdateWindow(hwndDlg);
// MoveAnchorsImmediatelly(hwndDlg);
break;
}
}
return TRUE;
}
return FALSE;
}
LRESULT CALLBACK DlgSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
static byte alpha = 255;
switch (uMsg)
{
case WM_ENTERSIZEMOVE:
printf("WM_ENTERSIZEMOVE\n");
return 0;
break;
case WM_EXITSIZEMOVE:
printf("WM_EXITSIZEMOVE\n");
return 0;
break;
case WM_MOUSEWHEEL:
if (((SHORT)(HIWORD(wParam))) > 0)
{
if (alpha > 30)
alpha -= 5;
}
else if (alpha < 255)
alpha += 5;
SetLayeredWindowAttributes(hwnd, RGB(255,0,255), alpha, LWA_COLORKEY|LWA_ALPHA);
UpdateWindow(hwnd);
return 0;
case WM_DMWNCRENDERINGCHANGED:
{
// printf("WM_DMWNCRENDERINGCHANGED\n");
long dwEx = GetWindowLong(hwnd, GWL_EXSTYLE);
dwEx |= WS_EX_LAYERED;
SetWindowLong(hwnd, GWL_EXSTYLE, dwEx);
SetLayeredWindowAttributes(hwnd, RGB(255,0,255), alpha, LWA_COLORKEY|LWA_ALPHA);
//MoveAnchorsImmediatelly(hwnd);
DeferAnchorsMove(hwnd);
InvalidateRect(hwnd, NULL, true);
UpdateWindow(hwnd);
// showWndRect(hwnd);
return 0;
}
break;
case WM_NCACTIVATE:
case WM_NCPAINT:
// printf("WM_NCPAINT -");
// printf("wParam: 0x%08d lParam 0x%08x\n", wParam, lParam);
onNcPaint(hwnd, wParam, lParam);
return 0;
case WM_NCCALCSIZE:
{
RECT *rc = (RECT*)lParam;
rc->left += 8; // frame image margin widths
rc->top += 30;
rc->right -= 8;
rc->bottom -= 8;
// rc->left += 14; // frame image margin widths
// rc->top += 39;
// rc->right -= 14;
// rc->bottom -= 14;
}
return (WVR_HREDRAW | WVR_VREDRAW);
case WM_NCHITTEST:
{
POINT mousePos, rawMousePos;
RECT clientRect, windowRect;
mousePos.x = LOWORD(lParam);
mousePos.y = HIWORD(lParam);
rawMousePos = mousePos;
GetClientRect(hwnd, &clientRect);
GetWindowRect(hwnd, &windowRect);
ScreenToClient(hwnd, &mousePos);
if ((mousePos.x < clientRect.left) && (rawMousePos.y < windowRect.top+8))
return HTTOPLEFT;
if ((mousePos.x > clientRect.right) && (rawMousePos.y < windowRect.top+8))
return HTTOPRIGHT;
if ( (mousePos.x < clientRect.left) && (mousePos.y > clientRect.bottom))
return HTBOTTOMLEFT;
if ( (mousePos.x > clientRect.right) && (mousePos.y > clientRect.bottom))
return HTBOTTOMRIGHT;
if (rawMousePos.x < windowRect.left+11)
return HTLEFT;
if (rawMousePos.x > windowRect.right-11)
return HTRIGHT;
if (mousePos.y > clientRect.bottom)
return HTBOTTOM;
RECT closeRect;
SetRect(&closeRect, windowRect.left + 15, windowRect.top+7, windowRect.left+15+16, windowRect.top+25);
if (PtInRect(&closeRect, rawMousePos))
{
// printf("over sys menu (appIcon) - %d,%d\n", mousePos.x, mousePos.y);
return HTSYSMENU;
}
if (rawMousePos.y < windowRect.top+8)
return HTTOP;
if (mousePos.y < 0)
return HTCAPTION;
else
return HTCLIENT;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
// return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT onNcPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
// draw Frame
// HBRUSH mBrush = CreateSolidBrush( RGB(0,113,201) );
HDC hdc = GetWindowDC(hwnd);
// HDC hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW);//|DCX_INTERSECTRGN);
RECT mRect, wndRect;
GetWindowRect(hwnd, &mRect);
wndRect = mRect;
mRect.right -= mRect.left;
mRect.bottom -= mRect.top;
mRect.left = 0;
mRect.top = 0;
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP old, memBmp;
old = (HBITMAP)GetCurrentObject(memDC, OBJ_BITMAP);
memBmp = CreateCompatibleBitmap(hdc, mRect.right, mRect.bottom);
//memBmp = zCreateDibSection(hdc, mRect.right, mRect.bottom, 24);
SelectObject(memDC, memBmp);
//StretchNineDraw(HDC destDC, RECT destRect, HBITMAP srcImage, RECT srcRect,
// int marginLeft, int marginTop, int marginRight, int marginBottom, int alpha);
if (frameIndex == 0)
// StretchNineDraw(memDC, mRect, frameImg, (RECT){0,0,33,58}, 16,41,16,16, 255);
StretchNineDrawNoAlpha(memDC, mRect, frameImg, (RECT){0,0,33,58}, 16,41,16,16);
else
StretchNineDraw(memDC, mRect, frameRedImg, (RECT){0,0,33,58}, 16,41,16,16, 255);
// StretchNineDrawNoAlpha(memDC, mRect, frameRedImg, (RECT){0,0,33,58}, 16,41,16,16);
// StretchNineDrawNoAlpha(memDC, mRect, frameOrigImg, (RECT){0,0,17,39}, 8,30,8,8);
//1111drawImgNineSquareStretching(memDC, mRect, frameImg, (RECT){0,0,33,58}, 16,41,16,16);
//void StretchNineDrawNoAlpha(HDC destDC, RECT destRect, HBITMAP srcImage, RECT srcRect,
// int marginLeft, int marginTop, int marginRight, int marginBottom)
// draw icon
HICON smallIcon = LoadIcon (NULL, IDI_APPLICATION);
DrawIconEx(memDC, 15, 9, smallIcon, 16, 16, 0,0, DI_NORMAL );
// draw window text
wchar_t wndText[100];
RECT textRect;
textRect.left = 9 + 16 + 9;
textRect.top = 0;
textRect.right = 1000;
textRect.bottom = 32;
GetWindowText(hwnd, wndText, 99);
//int oldMode = SetBkMode(hdc, TRANSPARENT);
//int oldMode = SetBkMode(memDC, TRANSPARENT);
SetBkMode(memDC, TRANSPARENT);
HFONT oldFont, hfont0 = CreateFont(-13, 0, 0, 0, 0, FALSE, FALSE, FALSE, 1, 0, 0, 0, 0, (L"Ms Shell Dlg"));
oldFont = (HFONT)SelectObject(memDC, hfont0);
DrawText(memDC, wndText, -1, &textRect, DT_VCENTER|DT_SINGLELINE|DT_LEFT);
SelectObject(memDC, oldFont);
DeleteObject(hfont0);
// top slice
BitBlt(hdc, 0,0, mRect.right,41, memDC, 0,0, SRCCOPY);
// left edge
BitBlt(hdc, 0, mRect.top + 41, 16, mRect.bottom - (41+16),
memDC, 0, mRect.top + 41, SRCCOPY);
// right edge
BitBlt(hdc, mRect.right-16, mRect.top + 41, 16, mRect.bottom - (41+16),
memDC, mRect.right-16, mRect.top + 41, SRCCOPY);
// bottom slice
BitBlt(hdc, 0,mRect.bottom-16, mRect.right,16, memDC, 0,mRect.bottom-16, SRCCOPY);
// BitBlt(hdc, 0,0, mRect.right,mRect.bottom, memDC, 0,0, SRCCOPY);
ReleaseDC(hwnd, hdc);
SelectObject(memDC, old);
DeleteDC(memDC);
DeleteObject(memBmp);
// ValidateRgn(hwnd, (HRGN)wParam);
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
frameImg = mLoadImageFile(L"frame.png");
frameRedImg = mLoadImageFile(L"frameRed.png");
frameOrigImg = mLoadImageFile(L"frameOrig.png");
hInst=hInstance;
InitCommonControls();
int result = DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
GdiplusShutdown(gdiplusToken);
return result;
}
在下面找到以下功能: - 加载 png 文件(使用 GDI+) - 将此图像拉伸(stretch)到边框上
/* BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF */
HBITMAP mLoadImageFile(wchar_t *filename)
{
HBITMAP result = NULL;
Bitmap bitmap(filename, false);
bitmap.GetHBITMAP(0, &result);
return result;
}
void GetRectSize(LPRECT tgt, int *width, int *height)
{
*width = (tgt->right - tgt->left) + 1;
*height = (tgt->bottom - tgt->top) + 1;
}
BOOL SetRectSizePos(LPRECT tgt, int xPos, int yPos, int width, int height)
{
return SetRect(tgt, xPos, yPos, xPos+(width-1), yPos+(height-1));
}
BOOL MoveRect(LPRECT tgt, int newX, int newY)
{
int width, height;
GetRectSize(tgt, &width, &height);
return SetRectSizePos(tgt, newX,newY, width,height);
}
// ****** marginLeft = 6
// ....|....|.... *
// ..tL.|.tM.|.tR.. *
// ---------------- * marginTop = 3
// ..mL.|.mM.|.mR..
// ---------------- * marginBottom = 3
// ..bL.|.bM.|.bR.. *
// ....|....|.... *
// ****** marginRight = 6
void CalcNineRects(LPRECT srcRect, RECT *dest, int marginLeft, int marginTop, int marginRight, int marginBottom)
{
int srcWidth, srcHeight;
int leftWidth, midWidth, rightWidth;
int topHeight, midHeight, botHeight;
int xOrig, yOrig;
GetRectSize(srcRect, &srcWidth, &srcHeight);
xOrig = srcRect->left;
yOrig = srcRect->top;
leftWidth = marginLeft;
midWidth = srcWidth - (marginLeft + marginRight) - 1;
rightWidth = marginRight;
topHeight = marginTop;
midHeight = srcHeight - (marginTop + marginBottom) - 1;
botHeight = marginBottom;
SetRectSizePos(&dest[0], xOrig, yOrig, leftWidth, topHeight);
SetRectSizePos(&dest[1], xOrig+(leftWidth), yOrig, midWidth, topHeight);
SetRectSizePos(&dest[2], xOrig+(leftWidth+midWidth), yOrig, rightWidth, topHeight);
SetRectSizePos(&dest[3], xOrig, yOrig+(topHeight), leftWidth, midHeight);
SetRectSizePos(&dest[4], xOrig+(leftWidth), yOrig+(topHeight), midWidth, midHeight);
SetRectSizePos(&dest[5], xOrig+(leftWidth+midWidth), yOrig+(topHeight), rightWidth, midHeight);
SetRectSizePos(&dest[6], xOrig,yOrig+(topHeight+midHeight), leftWidth, botHeight);
SetRectSizePos(&dest[7], xOrig+(leftWidth), yOrig+(topHeight+midHeight), midWidth, botHeight);
SetRectSizePos(&dest[8], xOrig+(leftWidth+midWidth), yOrig+(topHeight+midHeight), rightWidth, botHeight);
}
void StretchNineDraw(HDC destDC, RECT destRect, HBITMAP srcImage, RECT srcRect,
int marginLeft, int marginTop, int marginRight, int marginBottom,int alpha)
{
RECT destRectList[9], srcRectList[9];
int i;
int curSrcWidth, curSrcHeight, curDestWidth, curDestHeight;
HDC srcDC;
HBITMAP oldSrcBmp;
srcDC = CreateCompatibleDC(destDC);
// GetCurrentObject(srcDC, OBJ_BITMAP);
oldSrcBmp = (HBITMAP) SelectObject(srcDC, srcImage);
BLENDFUNCTION bf = {AC_SRC_OVER,0,alpha,AC_SRC_ALPHA};
int destHeight, destWidth;
GetRectSize(&destRect, &destWidth, &destHeight);
CalcNineRects(&srcRect, srcRectList, marginLeft, marginTop, marginRight, marginBottom);
CalcNineRects(&destRect, destRectList, marginLeft, marginTop, marginRight, marginBottom);
// printf("dst rect: %d,%d - %d,%d -- \n", destRect.left, destRect.top, destRect.right,destRect.bottom);
for (i=0; i<9; i++)
{
GetRectSize(&srcRectList[i], &curSrcWidth, &curSrcHeight);
GetRectSize(&destRectList[i], &curDestWidth, &curDestHeight);
AlphaBlend( destDC,
destRectList[i].left, destRectList[i].top,
curDestWidth, curDestHeight,
srcDC,
srcRectList[i].left, srcRectList[i].top,
curSrcWidth, curSrcHeight,
bf
);
}
SelectObject(srcDC, oldSrcBmp);
DeleteDC(srcDC);
}
最后,将控件锚定到窗口的代码(窗口调整大小时自动重新计算它们的位置)
typedef struct ANCHORPROPERTY
{
long anchorType;
RECT rc;
} *pANCHORPROPERTY;
#define ANCHOR_NONE 0
#define ANCHOR_WIDTH 1
#define ANCHOR_RIGHT 2
#define ANCHOR_CENTER_HORZ 3
#define ANCHOR_HEIGHT 4
#define ANCHOR_HEIGHT_WIDTH 5
#define ANCHOR_HEIGHT_RIGHT 6
#define ANCHOR_BOTTOM 7
#define ANCHOR_BOTTOM_WIDTH 8
#define ANCHOR_BOTTOM_RIGHT 9
#define ANCHOR_CENTER_HORZ_BOTTOM 10
#define ANCHOR_CENTER_VERT 11
#define ANCHOR_CENTER_VERT_RIGHT 12
#define ANCHOR_CENTER 13
pANCHORPROPERTY getWndAnchor(HWND hwnd);
bool removeAnchor(HWND hwnd);
bool mSetAnchorMode(HWND hwnd, long anchorMode);
BOOL CALLBACK AnchorEnum(HWND hwnd, LPARAM lParam);
void MoveAnchorsImmediatelly(HWND controlParent);
void DeferAnchorsMove(HWND controlParent);
long getChildCount(HWND controlParent);
pANCHORPROPERTY getWndAnchor(HWND hwnd)
{
return (pANCHORPROPERTY)GetProp(hwnd, L"anchor");
}
bool removeAnchor(HWND hwnd)
{
pANCHORPROPERTY pAnchor;
if (GetProp(hwnd, L"anchor") != NULL)
{
pAnchor = (pANCHORPROPERTY)RemoveProp(hwnd, L"anchor");
delete pAnchor;
}
return false;
}
bool mSetAnchorMode(HWND hwnd, long anchorMode)
{
bool result = false;
RECT rc, pr;
POINT p;
if (IsWindow(hwnd))
{
pANCHORPROPERTY pAnchor;
pAnchor = getWndAnchor(hwnd);
if (pAnchor == NULL)
{
pAnchor = new ANCHORPROPERTY;
SetProp(hwnd, L"anchor", pAnchor);
}
GetWindowRect(hwnd, &rc);
p.x = rc.left;
p.y = rc.top;
ScreenToClient( GetParent(hwnd), &p);
GetClientRect( GetParent(hwnd), &pr);
// printf("pos: %d,%d\n", p.x, p.y);
pAnchor->anchorType = mmin( mmax(anchorMode, ANCHOR_NONE), ANCHOR_CENTER);
pAnchor->rc.left = p.x;
pAnchor->rc.top = p.y;
pAnchor->rc.right = pr.right - (rc.right-rc.left + p.x);
pAnchor->rc.bottom = pr.bottom - (rc.bottom - rc.top + p.y);
result = true;
}
return result;
}
BOOL CALLBACK AnchorEnum(HWND hwnd, LPARAM lParam)
{
RECT pr, rc;
long x,y,xW,yH;
pANCHORPROPERTY pAnchor;
pAnchor = (pANCHORPROPERTY)GetProp(hwnd, L"anchor");
if (pAnchor != NULL)
{
if (pAnchor->anchorType != ANCHOR_NONE)
{
// printf("child enumerated - %d\n", pAnchor->anchorType);
RECT client, wnd;
GetClientRect(hwnd, &client);
GetWindowRect(hwnd, &wnd);
// printf("WndRect: %d x %d", (wnd.right-wnd.left) + 1, (wnd.bottom-wnd.top)+1);
// printf("client: %d x %d", client.right-client.left+1, client.bottom-client.top+1 );
int wW, wH, cW,cH;
wW = (wnd.right-wnd.left) + 1;
wH = (wnd.bottom-wnd.top) + 1;
cW = (client.right-client.left) + 1;
cH = (client.bottom-client.top) + 1;
GetClientRect(hwnd, &rc);
GetClientRect(GetParent(hwnd), &pr);
switch (pAnchor->anchorType)
{
case ANCHOR_WIDTH:
x = pAnchor->rc.left;
y = pAnchor->rc.top;
xW = mmax(pr.right - pAnchor->rc.left - pAnchor->rc.right, 0);
yH = rc.bottom;
break;
case ANCHOR_RIGHT: // = 2
x = (pr.right - rc.right - pAnchor->rc.right) - (wW-cW);
y = pAnchor->rc.top;
xW = rc.right + (wW-cW);
yH = rc.bottom + (wH-cH);
// printf("xPos, yPos: %d, %d - Size: %d x %d\n", x,y,xW,yH);
break;
case ANCHOR_CENTER_HORZ: // = 3
x = (pr.right - rc.right) / 2;
y = pAnchor->rc.top;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_HEIGHT: // = 4
x = pAnchor->rc.left;
y = pAnchor->rc.top;
xW = rc.right;
yH = mmax(pr.bottom - pAnchor->rc.top - pAnchor->rc.bottom, 0);
break;
case ANCHOR_HEIGHT_WIDTH: // = 5
x = pAnchor->rc.left;
y = pAnchor->rc.top;
xW = mmax(pr.right - pAnchor->rc.left - pAnchor->rc.right, 0);
yH = mmax(pr.bottom - pAnchor->rc.top - pAnchor->rc.bottom, 0);
break;
case ANCHOR_HEIGHT_RIGHT: // = 6
x = pr.right - rc.right - pAnchor->rc.right;
y = pAnchor->rc.top;
xW = rc.right;
yH = mmax(pr.bottom - pAnchor->rc.top - pAnchor->rc.bottom, 0);
break;
case ANCHOR_BOTTOM: // = 7
x = pAnchor->rc.left;
y = pr.bottom - pAnchor->rc.bottom - rc.bottom;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_BOTTOM_WIDTH: // = 8
x = pAnchor->rc.left;
y = pr.bottom - pAnchor->rc.bottom - rc.bottom;
xW = mmax(pr.right - pAnchor->rc.left - pAnchor->rc.right, 0);
yH = rc.bottom;
break;
case ANCHOR_BOTTOM_RIGHT: // = 9
x = pr.right - rc.right - pAnchor->rc.right;
y = pr.bottom - pAnchor->rc.bottom - rc.bottom;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_CENTER_HORZ_BOTTOM: // = 10
x = (pr.right - rc.right) / 2;
y = pr.bottom - pAnchor->rc.bottom - rc.bottom;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_CENTER_VERT: // = 11
x = pAnchor->rc.left;
y = (pr.bottom - rc.bottom) / 2;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_CENTER_VERT_RIGHT: // = 12
x = pr.right - rc.right - pAnchor->rc.right;
y = (pr.bottom - rc.bottom) / 2;
xW = rc.right;
yH = rc.bottom;
break;
case ANCHOR_CENTER: // = 13
x = (pr.right - rc.right) / 2;
y = (pr.bottom - rc.bottom) / 2;
xW = rc.right;
yH = rc.bottom;
break;
}
if (lParam == 0)
SetWindowPos(hwnd,0, x,y, xW,yH, SWP_NOZORDER|SWP_NOCOPYBITS);
else
DeferWindowPos((HDWP)lParam, hwnd, 0, x,y, xW,yH, SWP_NOZORDER|SWP_NOCOPYBITS);
}
}
return true;
}
void MoveAnchorsImmediatelly(HWND controlParent)
{
EnumChildWindows(controlParent, AnchorEnum, 0);
}
BOOL CALLBACK CountEnum(HWND hwnd, LPARAM lParam)
{
long *pCount = (long*)lParam;
++(*pCount);
return true;
}
long getChildCount(HWND controlParent)
{
long curCount = 0;
EnumChildWindows(controlParent, CountEnum, (LPARAM)&curCount);
// printf("Child count: %d\n", curCount);
return curCount;
}
void DeferAnchorsMove(HWND controlParent)
{
HDWP deferMoveHandle;
int childCount = getChildCount(controlParent);
deferMoveHandle = BeginDeferWindowPos(childCount);
EnumChildWindows(controlParent, AnchorEnum, (LPARAM)deferMoveHandle);
EndDeferWindowPos(deferMoveHandle);
}
关于c++ - 更改 win32 应用程序标题栏(标题)的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39261826/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘