I have create my toolbar from the application, only 4 buttons and each button has the size of 80 by 64 pixels. The whole bitmap is 320 by 64.
const int numButtons = 4;
const SIZE bitmapSize={80,64};
HIMAGELIST hImageList = ImageList_Create(bitmapSize.cx, bitmapSize.cy, ILC_COLOR16 | ILC_MASK,numButtons, 0);
HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_HOME));
int iImageList = ImageList_AddMasked(hImageList, hBitmap, 0);
SendMessage(hWndToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList);
TBBUTTON tbButtons[numButtons] =
{
{ 0, WM_BBBB1, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0},
{ 1, WM_BBBB2, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0},
{ 2, WM_BBBB3, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0},
{ 3, WM_BBBB4, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0}
};
// Add buttons.
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(hWndToolbar, TB_ADDBUTTONS,(WPARAM)numButtons,(LPARAM)&tbButtons);
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
RECT _tbRect;
SendMessage(hWndToolbar, TB_GETITEMRECT, 0, (LPARAM)&_tbRect);//0,0,87,70
It says the button has 87 in width and 70 in height, if my bitmap has its own bounding size and I don't want the control to add the bounding rectangle for toolbar, how can I do?
Thank you in advance!
Try to call
SendMessage(hWndToolbar, TB_SETBUTTONSIZE, 0, (LPARAM)MAKELONG(80,64)); // or some wanted values
after TB_ADDBUTTONS
Related
I can currently draw the triangle, set the background as Red, but I can't color the triangle. What obvious step am I missing here?
Current Progress - Red background and black triangle
const GLfloat vertices[] = {
vertex1_s, vertex1_t, 0,
vertex2_s, vertex2_t, 0,
vertex3_s, vertex3_t, 0
};
glClearColor(1,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
const GLfloat colors[] = {
0, 0, 1,
0, 0, 1,
0, 0, 1
};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(dpy, surface);
I'm studying WinAPI double buffering, and when I run the code below, the screen flickers too much. I think I did it right, but where is the problem?
Draw memdc1 and memdc2 to memdc, and memdc to hdc.
switch (iMsg)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetClientRect(hwnd, &clientRt);
PlaceCenterScreen(hwnd);
SetTimer(hwnd, 1, 10, NULL);
hMixBit = CreateCompatibleBitmap(hdc, 819, 614);
hHouseBit = (HBITMAP)LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_HOUSE));
hTigerBit = (HBITMAP)LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_TIGER));
ReleaseDC(hwnd, hdc);
break;
case WM_TIMER:
posX += 3;
InvalidateRgn(hwnd, NULL, true);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
memdc = CreateCompatibleDC(hdc);
memdc1 = CreateCompatibleDC(memdc);
memdc2 = CreateCompatibleDC(memdc);
oldHouseBit = (HBITMAP)SelectObject(memdc1, hHouseBit);
oldTigerBit = (HBITMAP)SelectObject(memdc2, hTigerBit);
oldMixBit = (HBITMAP)SelectObject(memdc, hMixBit);
BitBlt(memdc, 0, 0, 819, 614, memdc1, 0, 0, SRCCOPY);
BitBlt(memdc, posX, 0, 67, 47, memdc2, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, 819, 614, memdc, 0, 0, SRCCOPY);
SelectObject(memdc1, oldHouseBit);
SelectObject(memdc2, oldTigerBit);
SelectObject(memdc, oldMixBit);
I'm trying to start experimenting with OpenGL and Windows GUI stuff. I'm running Windows 7 on my dev box and running Visual Studio 2013. When I run the below code, I don't receive any errors and all the of window information seems correct but nothing is drawn to the screen from OpenGL.
For a first program I was looking to put an overlay on top of Notepad, then draw a line/plus sign somewhere in the screen.
First I create a window:
myWindow = CreateWindowEx(
WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_LAYERED,
WINDOW_NAME,
WINDOW_NAME,
WS_POPUP | WS_VISIBLE | WS_MAXIMIZE,
g_NotepadCoords.left,
g_NotepadCoords.top,
g_width,
g_height,
NULL, NULL, g_me, NULL);
The globals and coordinates for the window are calculated using FindWindowA and GetClientRect. Both of these function calls succeed and return reasonable values. After CreateWindowEx, I use the following function calls to set properties and check support, etc:
SetLayeredWindowAttributes(myWindow, RGB(0, 0, 0), 255, LWA_ALPHA | LWA_COLORKEY);
if (S_OK != DwmIsCompositionEnabled(&bIsEnabled)){...}
Right now HandleWindowMessage has WM_CREATE, WM_CLOSE, WM_DESTROY and WM_PAINT enabled. SetupOpenGL is called in WM_CREATE, and the drawing happens in WM_PAINT.
WM_CREATE and WM_PAINT:
case WM_CREATE:
{
printf("WM_CREATE\n");
g_Hdc = GetDC(hWnd);
SetupGL();
return 0;
}
break;
case WM_PAINT:
{
GLenum err;
const GLubyte *errString;
RGB colorToDraw = { 0 };
drawPlus(g_.middleX, g_.middleY, 12, 12, 4, &colorToDraw);
err = glGetError();
errString = gluErrorString(err);
printf("ERROR DRAWING? %s\n", errString);
}
break;
As far as I can tell I set up OpenGL correctly; no errors are printed:
void SetupOpenGL()
{
__try{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | // Format Must Support Window, OPENGL, Composition
PFD_SUPPORT_OPENGL |
PFD_SUPPORT_COMPOSITION |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // RGBA
32,
0, 0, 0, 0, 0, 0,
8, // alpha
0, 0, 0, 0, 0, 0, 0,
8, // stencil Buffer
0,
PFD_MAIN_PLANE, // Main Drawing Layer
0, 0, 0, 0
};
PixelFormat = ChoosePixelFormat(g_Hdc, &pfd);
if (0 == PixelFormat)
{
printf("ChoosePixelFormat failed %d\n", GetLastError());
__leave;
}
if (!SetPixelFormat(g_Hdc, PixelFormat, &pfd))
{
printf("SetPixelFormat failed %d\n", GetLastError());
__leave;
}
if (!DescribePixelFormat(g_Hdc, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
{
printf("DescribePixelFormat failed %d\n", GetLastError());
__leave;
}
g_MainHGLRC = wglCreateContext(g_Hdc);
if (!g_MainHGLRC)
{
printf("wglCreateContext failed %d\n", GetLastError());
__leave;
}
if (!wglMakeCurrent(g_Hdc, g_MainHGLRC))
{
printf("wglMakeCurrent failed %d\n", GetLastError());
__leave;
}
glMatrixMode(GL_PROJECTION);
glClearColor(0.f, 0.f, 0.f, 0.f);
}
__finally{}
}
And then drawPlus is super simple:
void drawPlus(float x, float y, float width, float height, float lineWidth, RGB* RGB)
{
printf("drawPlus(%f,%f,%f,%f,%f,[%d,%d,%d])", x, y, width, height, lineWidth, RGB->red, RGB->green, RGB->blue);
glLineWidth(lineWidth);
glBegin(GL_LINES);
glColor4f(RGB->red, RGB->green, RGB->blue, 1);
glVertex2f(x, y + height/2);
glVertex2f(x, y - height/2);
glVertex2f(x + width/2, y);
glVertex2f(x - width/2, y);
glEnd();
}
When I run it, I don't receive any errors, I can see the executable creating another window and I've confirmed that drawPlus is getting called correctly and with good parameters. However, there's nothing actually drawn to the screen so I'm not sure what I'm missing. I just ran a quick check on the coordinates and for the Notepad windows elements I got:
top: 86
bottom: 916
left: 170
right: 609
And then for where to draw the plus I got
x = 219
y = 412
Which both seem reasonable so it's not my windows being mismatched or etc.
Im trying to render a texture keeping its ratio in openGL es 2.0 .
I suppose I need to calculate the ratio and change the frustum dimensions, is that the right way?
Right now Im rendering with frustum -1,1 for width and height so the texture gets stretched when it doesnt have the screen size.
How do I render the texture lets say width = 400 height = 800 at that ratio?
This is my code :
#Override
public void onDrawFrame(GL10 glUnused) {
GLES20.glClearColor(0.9f, 0.9f, 0.9f, .5f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glEnable( GLES20.GL_BLEND );
GLES20.glBlendFunc( GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA );
Matrix.setIdentityM(mMMatrix, 0);
Matrix.rotateM(mMMatrix, 0, 270.0f, 0, 0, 1);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUseProgram(programTextured);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
GLES20.glVertexAttribPointer(
GLES20.glGetAttribLocation(programTextured, "aPosition"), 3,
GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));
sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
GLES20.glVertexAttribPointer(
GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));
GLES20.glUniformMatrix4fv(
GLES20.glGetUniformLocation(programTextured, "uMVPMatrix"), 1, false,
mMVPMatrix, 0);
GLES20.glVertexAttrib4f(
GLES20.glGetAttribLocation(programTextured, "acolor"),
.6f,0.3f,0.9f,.5f);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, sqTex.getIndexBuffer());
GLES20.glDisableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));
}
#Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
//flaot ratio2 = (float)height /
//Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3f, 17);
Matrix.frustumM(mProjMatrix, 0, -1, 1, -1, 1, 3, 17);
}
int mTextureID;
#Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
program = createProgram(mVertexShader, mFragmentShader);
programTextured = createProgram(mVertexShaderTextured, mFragmentShaderTextured);
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
mTextureID = textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_REPEAT);
InputStream is = mContext.getResources()
.openRawResource(R.drawable.image0003);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch(IOException e) {
// Ignore.
}
}
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
I would leave the frustum and rather use scale:
You need 2 factors, first a screenRatio = screenWidth/screenHeight, then imageRatio = imageWidth/imageHeight.
Now if imageRatio < screenRatio you will need to scale it down in width:
if (imageWidth>imageHeight) scaleM(mMMatrix, 1/(imageWidth/imageHeight), 1, 1)
else scaleM(mMMatrix, 1/(imageHeight/imageWidth), 1, 1)
Or if imageRatio > screenRatio you will need to scale it down in height:
if (imageHeight>imageWidth) scaleM(mMMatrix, 1, 1/(imageHeight/imageWidth), 1)
else scaleM(mMMatrix, 1, 1/(imageWidth/imageHeight), 1)
I attampted to draw a irregular window with the UpdateLayeredWindow(), in msvc2008, xp sp3.
Here is part of my code:
//Add something(CreateWindowEx()):
hwndCyauWnd = CreateWindowEx(
/*WS_EX_TOOLWINDOW |*/ WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_LAYERED,
lpwsCyauClassName,
lpwsCyauWndName,
WS_CLIPSIBLINGS | WS_POPUP,
GetSystemMetrics(SM_CXSCREEN)-320,
GetSystemMetrics(SM_CYSCREEN)-232,
320, 200,
NULL,
NULL,
hInstance,
NULL);
//Skip Lines
HDC hdcCyauWnd = GetDC(hwndCyauWnd);
HDC hdcBuffer = CreateCompatibleDC(hdcCyauWnd);
//HBITMAP hbmCyau = CreateCompatibleBitmap(hdcBuffer,120, 93);
//SelectObject(hdcBuffer, hbmCyau);
POINT ptZero = {0, 0};
POINT ptDrawPos = {0, 0};
RECT rctCyauWnd;
GetWindowRect(hwndCyauWnd, &rctCyauWnd);
SIZE szCyauWnd={rctCyauWnd.right - rctCyauWnd.left, rctCyauWnd.bottom - rctCyauWnd.top};
BLENDFUNCTION blendPixelFunction = { AC_SRC_OVER, 0, 100, AC_SRC_ALPHA};
Graphics gphCyauWnd(hdcBuffer);
Image imgCyau(L"surface0000.png");
gphCyauWnd.DrawImage(&imgCyau, 0, 0, 125, 93);
UpdateLayeredWindow(hwndCyauWnd,
hdcCyauWnd, &ptZero,
&szCyauWnd,
hdcBuffer, &ptZero,
0, //RGB(255, 255, 255),
&blendPixelFunction,
ULW_ALPHA);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
I have tried several method to use this function, but all failed, NOTHING APPEAR on the screen.
Could anybody tell me what happens and how to slove it?
Add:
Whole source file have been upload to my skydrive, anyone can edit, much appreciation! (I have become a poor underdog now...)
You mixed up GDI and GDI+, which is not a good idea. Here is a working example:
hWnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, 0,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
// Load PNG
CImage img;
img.Load("BACKGR.png");
// Get image sizes
int nWidth = img.GetWidth();
int nHeight = img.GetHeight();
// Create memory DC
HDC hdcScreen = GetDC(NULL);
HDC hDC = CreateCompatibleDC(hdcScreen);
// Create memory bitmap
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
// Draw image to memory bitmap (currently selected in memory DC)
img.Draw(hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight);
// Call UpdateLayeredWindow
BLENDFUNCTION blend = {0};
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 128;// half transparent
blend.AlphaFormat = AC_SRC_ALPHA;
POINT ptLocation = {0, 0};
SIZE szWnd = {nWidth, nHeight};
POINT ptSrc = {0, 0};
UpdateLayeredWindow(hWnd, hdcScreen, &ptLocation, &szWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);
ShowWindow(hWnd, SW_SHOW);
SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
ReleaseDC(NULL, hdcScreen);
If you want GDI+ to draw to an image with an alpha channel, you have to draw to a Bitmap, not an HDC, and you have to specify that the Bitmap's format has alpha. To do that with an HBITMAP, you have to also point GDI+ to the bitmap bits.
Something like this:
BITMAPINFOHEADER bih;
HBITMAP hbmp;
HDC hdc;
void *bits;
bih.biSize = sizeof(bih);
bih.biWidth = width;
bih.biHeight = -height;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
hdc = CreateCompatibleDC(NULL);
hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &bits, NULL, 0);
Bitmap bitmap(width, height, 0, PixelFormat32bppPARGB, bits);
Graphics graphics(bitmap);
graphics->DrawWhatever(...);
graphics->Flush();
SelectObject(hdc, hbitmap);
UpdateLayeredWindow(hwnd, hdc, ...