Convert Gtk.TreeView into a text format - treeview

I'm trying to export a Gtk.TreeView into a text format. This is like an export to text function on an application which presents data in a TreeView using the ListStore model.
Can someone help with a sample code on how to efficiently parse a Gtk.TreeView and represent it in a simple text format.

As a starting point consider this code from valadoc:
public static int main (string[] args) {
// Create a ListStore:
Gtk.ListStore list_store = new Gtk.ListStore (2, typeof (string), typeof (int));
Gtk.TreeIter iter;
// Insert data: (0: State, 1: Cities)
list_store.append (out iter);
list_store.set (iter, 0, "Burgenland", 1, 13);
list_store.append (out iter);
list_store.set (iter, 0, "Carinthia", 1, 17);
list_store.append (out iter);
list_store.set (iter, 0, "Lower Austria", 1, 75);
list_store.append (out iter);
list_store.set (iter, 0, "Upper Austria", 1, 32);
list_store.append (out iter);
list_store.set (iter, 0, "Salzburg", 1, 10);
list_store.append (out iter);
list_store.set (iter, 0, "Styria", 1, 34);
list_store.append (out iter);
list_store.set (iter, 0, "Tyrol", 1, 11);
list_store.append (out iter);
list_store.set (iter, 0, "Vorarlberg", 1, 5);
list_store.append (out iter);
list_store.set (iter, 0, "Vienna", 1, 1);
// Output:
// ``Entry: Burgenland 13``
// ``Entry: Carinthia 17``
// ``Entry: Lower Austria 75``
// ``Entry: Upper Austria 32``
// ``Entry: Salzburg 10``
// ``Entry: Styria 34``
// ``Entry: Tyrol 11``
// ``Entry: Vorarlberg 5``
// ``Entry: Vienna 1``
for (bool next = list_store.get_iter_first (out iter); next; next = list_store.iter_next (ref iter)) {
Value val1, val2;
list_store.get_value (iter, 0, out val1);
list_store.get_value (iter, 1, out val2);
stdout.printf ("Entry: %s\t%d\n", (string) val1, (int) val2);
}
return 0;
}
You should also read the top level documentation for the Gtk.TreeModel interface.

Related

Draw cursor multiple display (only draw text icon) GDI

I select displays in multiple display environments and produce captured programs.
And try to draw a cursor by selecting dc among multiple displays.
I draw cursors with bitblt bitmap images and it works well.
HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);
But When I select from createDC multuple display value,
DISPLAY_DEVICEW info = { 0 };
info.cb = sizeof(DISPLAY_DEVICEW);
EnumDisplayDevicesW(NULL, 0, &info, EDD_GET_DEVICE_INTERFACE_NAME);
HDCC = CreateDC(info.DeviceName, NULL, NULL, NULL);
I am working hard to get other display images. But there is no drawing cursor. (Other forms of cursor are not drawn, only text cursor is drawn)
This is my code.
const int d_count = GetSystemMetrics(SM_CMONITORS); //I have 3 display and count is 3.
HDC hCaptureDC;
HDC HDCC;
HBITMAP hBitmap;
HGDIOBJ hOld;
BYTE *src;
bool GetMouse() {
CURSORINFO cursor = { sizeof(cursor) };
::GetCursorInfo(&cursor);
ICONINFOEXW info = { sizeof(info) };
::GetIconInfoExW(cursor.hCursor, &info);
BITMAP bmpCursor = { 0 };
GetObject(info.hbmColor, sizeof(bmpCursor), &bmpCursor);
POINT point;
GetCursorPos(&point);
bool res = DrawIconEx(hCaptureDC, point.x, point.y, cursor.hCursor, bmpCursor.bmWidth, bmpCursor.bmHeight, 0, NULL, DI_NORMAL);
return res;
}
void screencap(){
BITMAPINFO MyBMInfo;
BITMAPINFOHEADER bmpInfoHeader;
HWND m_hWndCopy= GetDesktopWindow();
GetClientRect(m_hWndCopy, &ImageRect);
const int nWidth = ImageRect.right - ImageRect.left;
const int nHeight = ImageRect.bottom - ImageRect.top;
MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
bmpInfoHeader = { sizeof(BITMAPINFOHEADER) };
bmpInfoHeader.biWidth = nWidth;
bmpInfoHeader.biHeight = nHeight;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
b_size = ((nWidth * bmpInfoHeader.biBitCount + 31) / 32) * 4 * nHeight;
//HDCC = CreateDC((L"Display"), NULL, NULL, NULL); //It's good.
DISPLAY_DEVICEW info = { 0 };
info.cb = sizeof(DISPLAY_DEVICEW);
EnumDisplayDevicesW(NULL, 0, &info, EDD_GET_DEVICE_INTERFACE_NAME);
HDCC = CreateDC(info.DeviceName, NULL, NULL, NULL); // It draws only text cursor.
hCaptureDC = CreateCompatibleDC(HDCC);
hBitmap = CreateCompatibleBitmap(HDCC, nWidth, nHeight);
hOld = SelectObject(hCaptureDC, hBitmap);
BitBlt(hCaptureDC, 0, 0, nWidth, nHeight, HDCC, 0, 0, SRCCOPY);
GetMouse();
SelectObject(hCaptureDC, hOld);
src = (BYTE*)malloc(b_size);
if (GetDIBits(hCaptureDC, hBitmap, 0, nHeight, src, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS)) {
if (RGBSaveBMP(src) == true)
free(src);
}
}
I'm using windows 10.
How can I solved?
Any links, idea, Thanks.
ADD
It does not draw cursor....(except text cursor.)
HDCC = CreateDC(TEXT("\\\\.\\Display1"), NULL, NULL, NULL);
It draws cursor..
HDCC = CreateDC(TEXT("Display"), NULL, NULL, NULL);
SOLVED:
Now, I changed my algorithm.
CreateDC(L"Display", NULL, NULL, NULL) create DC for all monitors, so what is your problem? – user2120666 Apr 22 at 15:37
This comment is very helpful but It was not kind. (Or I was stupid.) :(
HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);
HDCC has "All Virtual Screens" DC.
When I selected the monitor I needed, and accordingly selected and used the area to capture on the virtual screen.
HDC hCaptureDC = CreateCompatibleDC(HDCC);
HBITMAP hBitmap = CreateCompatibleBitmap(HDCC, nWidth, nHeight);
HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);
DEVMODE dev;
std::string str = "\\\\.\\Display" + std::to_string(select);
std::wstring temp;
temp.assign(str.begin(), str.end());
EnumDisplaySettingsW(temp.c_str(), ENUM_CURRENT_SETTINGS, &dev);
printf("Display%d : (%d * %d) (%d, %d)\n", select, dev.dmPelsWidth, dev.dmPelsHeight, dev.dmPosition.x, dev.dmPosition.y);
nWidth = dev.dmPelsWidth;
nHeight = dev.dmPelsHeight;
nposx = dev.dmPosition.x;
nposy = dev.dmPosition.y;
hOld = SelectObject(hCaptureDC, hBitmap);
BitBlt(hCaptureDC, 0, 0, nWidth, nHeight, HDCC, nposx, nposy, SRCCOPY);
int colorcheck = GetSystemMetrics(SM_SAMEDISPLAYFORMAT);
CURSORINFO cursor = { sizeof(cursor) };
bool check = ::GetCursorInfo(&cursor);
bool check2 = ::GetCursorInfo(&cursor);
int count = ShowCursor(TRUE);
info = { sizeof(info) };
::GetIconInfoExW(cursor.hCursor, &info);
GetCursorPos(&point);
if (point.x > nWidth) {
point.x = point.x - nWidth;
}
else if (point.x < 0) {
point.x = nWidth + point.x;
}
if (point.y > nHeight) {
point.y = point.y - nHeight;
}
else if (point.y < 0) {
point.y = nHeight + point.y;
}
cursor.ptScreenPos.x = point.x;
cursor.ptScreenPos.y = point.y;
bool res = ::DrawIconEx(hCaptureDC, point.x, point.y, cursor.hCursor, 0, 0, 0, NULL, DI_NORMAL);
BYTE* src = (BYTE*)malloc(b_size);
GetDIBits(hCaptureDC, hBitmap, 0, nHeight, src, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS)
Thanks for the comment!
Your call GetClientRect(m_hWndCopy, &ImageRect); is wrong.
From documentation:
The rectangle of the desktop window returned by GetWindowRect or
GetClientRect is always equal to the rectangle of the primary monitor,
for compatibility with existing applications.
So you are capturing only primary display.
Following MSDN to get EnumDisplayMonitor may solve your problem.
Use EnumDisplayMonitors to get the device name and pass it to
CreateDC.

Xcode sqlite3,use "insert" but fail and defined 1

I wanted to add a line to my table 'Cloth',but failed.I then set breakpoint and found the defined is 1.
Here's the code.
char *addCloth = "INSERT INTO 'Cloth'(Ckind,Ccolor,Cseason,Ctexture,Cstyly) VALUES(?,?,?,?,?);";
sqlite3_stmt *stmt;
int success = sqlite3_prepare_v2(db, addCloth, -1, &stmt, nil);
if(success!= SQLITE_OK){
NSLog(#"Error: failed to insert:testTable");
sqlite3_close(db);
}
sqlite3_bind_text(stmt, 1, [strkind UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 2, [strcolor UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 3, [seas UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 4, [texture UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 5, [style UTF8String], -1, NULL);
success = sqlite3_step(stmt);
if(success != SQLITE_DONE)
{sqlite3_close(db);
NSLog(#"单品新增失败");
}
sqlite3_finalize(stmt);
}
and the run image:enter image description here
it seems my 'stmt' is nil,so I doubt whether if my 'strkind' and 'strcolor'is Chinese character caused it.
Or something else where made this error?
Thanks

Navigating through a Maze using path-planning (Dijkstra)

I'm working on an robot that would be able to navigate through a maze, avoid obstacles and identify some of the objects in it. I have a monochromatic bitmap of the maze, that is supposed to be used in the robot navigation.
Up till now I have processed the bitmap image, and converted it into an adjacency list. I will now use the dijkstra's algorithm to plan the path.
However the problem is that I have to extract the entrance point/node and exit node from the bmp image itself for dijkstra's algorithm to plan the path.
The robots starting position will be slightly different (inch or two before the entrance point) from the entrance point of maze, and I am supposed to move to the entrance point using any "arbitrary method" and then apply dijkstra algorithm to plan path from maze's entrance to exit.
On the way I have to also stop at the "X's" marked in the bmp file I have attached below. These X's are basically boxes in which I have to pot balls. I will plan the path from entrance point to exit point , and not from the entrance to 1st box, then to second, and then to the exit point; because I think the boxes will always be placed at the shortest path.
Since the starting position is different from the entrance point, how will I match my robot's physical location with the coordinates in the program and move it accordingly. Even if the entrance position would have been same as starting position there may have been an error. How should I deal with it? Should I navigate only on the bases of the coordinates provided by dijkstra or use ultrasonics as well to prevent collisions? And if we yes, can you give me an idea of how should I use the both (ultrasonics, and coordinates)?
Here's the sample Bitmap image of the maze.
I know you need this for robotics but here is an example how to translate pixels to array in java to give some ideas?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class RobotDemo extends JFrame {
private static final long serialVersionUID = 1L;
public RobotDemo() {
super("Robot Demo");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new RobotPanel(), BorderLayout.CENTER);
pack();
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new RobotDemo();
frame.setVisible(true);
}
});
}
}
interface Constants {
public static final int TILE_WIDTH = 32;
public static final int TILE_HEIGHT = 32;
public static final int NUM_TILE_COLS = 20;
public static final int NUM_TILE_ROWS = 10;
public static final int PIXEL_STEPS = 3;
public static final int REFRESH_RATE = 200;
public static final Dimension PANEL_SIZE = new Dimension(TILE_WIDTH * NUM_TILE_COLS, TILE_HEIGHT * NUM_TILE_ROWS);
public static enum RobotState {
awaiting_instruction,
moving_north,
moving_south,
moving_east,
moving_west
};
public static enum RobotInstruction {
NORTH,
SOUTH,
EAST,
WEST
}
public void draw(Graphics g);
}
class RobotPanel extends JPanel implements Constants, ActionListener {
private static final long serialVersionUID = 1L;
private Timer timer = new Timer(REFRESH_RATE, this);
private Map map = new Map();
private Robot robot = new Robot(map);
public RobotPanel() {
timer.start();
}
public Dimension getPreferredSize() { return PANEL_SIZE; }
public Dimension getMinimumSize() { return PANEL_SIZE; }
public Dimension getMaximumSize() { return PANEL_SIZE; }
protected void paintComponent(Graphics g) {
super.paintComponent(g);
map.draw(g);
robot.draw(g);
draw(g);
}
public void actionPerformed(ActionEvent e) {
robot.update();
repaint();
}
public void draw(Graphics g) {
for(int r = 0; r < NUM_TILE_ROWS; r++) {
for(int c = 0; c < NUM_TILE_COLS; c++) {
g.drawRect(c * TILE_WIDTH, r * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
}
}
}
}
class Robot implements Constants {
private RobotState state = RobotState.moving_east;
private int row = TILE_HEIGHT;
private int col = TILE_WIDTH;
private int mapX = 1;
private int mapY = 1;
private Map map;
int nextRowCheck = 1;
int nextColCheck = 2;
public Robot(Map m) {
map = m;
}
public int getRow() {
return mapY;
}
public int getCol() {
return mapX;
}
private boolean needsNewInstruction(){
int newRow = row;
int newCol = col;
if(state == RobotState.moving_north) newRow -= PIXEL_STEPS;
if(state == RobotState.moving_south) newRow += PIXEL_STEPS;
if(state == RobotState.moving_east) newCol += PIXEL_STEPS;
if(state == RobotState.moving_west) newCol -= PIXEL_STEPS;
if((newRow / TILE_HEIGHT) != mapY) return true;
if((newCol / TILE_WIDTH) != mapX) return true;
return false;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.GREEN);
g.fillRect(col, row, TILE_WIDTH, TILE_HEIGHT);
g.setColor(c);
}
public void update() {
System.out.println("UPDATE [" + row + "][" + col + "] = [" + (row / TILE_HEIGHT) + "][" + (col / TILE_WIDTH) + "]");
if(needsNewInstruction()) {
System.out.println("NEEDS NEW INSTRUCTION [" + row + "][" + col + "] = [" + (row / TILE_HEIGHT) + "][" + (col / TILE_WIDTH) + "]");
mapX = nextColCheck;
mapY = nextRowCheck;
System.out.println("UPDATED MAP REFERENCE [" + mapY + "][" + mapX + "]");
row = mapY * TILE_HEIGHT;
col = mapX * TILE_WIDTH;
System.out.println("UPDATED PIXEL REFERENCE [" + row + "][" + col + "]");
RobotInstruction instruction = map.getNextInstruction(this);
if(instruction == RobotInstruction.NORTH) {
state = RobotState.moving_north;
nextRowCheck = mapY - 1;
}
if(instruction == RobotInstruction.SOUTH) {
state = RobotState.moving_south;
nextRowCheck = mapY + 1;
}
if(instruction == RobotInstruction.EAST) {
state = RobotState.moving_east;
nextColCheck = mapX + 1;
}
if(instruction == RobotInstruction.WEST) {
state = RobotState.moving_west;
nextColCheck = mapX - 1;
}
}
move();
}
public void move() {
if(state == RobotState.moving_north) row -= PIXEL_STEPS;
if(state == RobotState.moving_south) row += PIXEL_STEPS;
if(state == RobotState.moving_east) col += PIXEL_STEPS;
if(state == RobotState.moving_west) col -= PIXEL_STEPS;
}
}
class Map implements Constants {
int[][] map = new int[][] {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
public Map() {
}
public RobotInstruction getNextInstruction(Robot robot) {
int row = robot.getRow();
int col = robot.getCol();
System.out.println("GET NEXT INSTRUCTION FOR [" + row + "][" + col + "]");
if(map[row][col + 1] == 0) return RobotInstruction.EAST;
if(map[row + 1][col] == 0) return RobotInstruction.SOUTH;
if(map[row - 1][col] == 0) return RobotInstruction.NORTH;
if(map[row][col - 1] == 0) return RobotInstruction.WEST;
return null;
}
public void draw(Graphics g) {
Color color = g.getColor();
for(int r = 0; r < NUM_TILE_ROWS; r++) {
for(int c = 0; c < NUM_TILE_COLS; c++) {
g.setColor(map[r][c] == 0 ? Color.CYAN : Color.RED);
g.fillRect(c * TILE_WIDTH, r * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
}
}
g.setColor(color);
}
}
Here is an example how to populate your navigational array with directions. the code above doesn't use the code below so you would have to do that yourself ...
public class Maze {
private static final char E = 'E'; // Ending position
private static final char X = 'X'; // Wall
private static final char O = ' '; // Space
private static final char L = 'L'; // Left
private static final char R = 'R'; // Right
private static final char U = 'U'; // Up
private static final char D = 'D'; // Down
private static final char FALSE = '0'; // Not accessible
private static final char TRUE = '1'; // Is accessible
private static final Node END_NODE = new Node(4, 4);
private static final int[] ROW_DIRECTIONS = {-1, 1, 0, 0};
private static final int[] COL_DIRECTIONS = { 0, 0, -1, 1};
private static final char[][] OPPOSITES = new char[][] {{O, D, O},{R, O, L},{O, U, O}};
public static void main(String[] args) {
char[][] maze = new char[][] {
{X, X, X, X, X, X},
{X, O, O, X, O, X},
{X, O, X, X, O, X},
{X, O, O, O, X, X},
{X, X, O, X, O, X},
{X, O, O, O, O, X},
{X, O, X, X, O, X},
{X, X, X, X, X, X}};
// PLOT THE DESTINATION CELL AND ADD IT TO LIST
List<Node> nodes = new ArrayList<Node>();
nodes.add(END_NODE);
maze[END_NODE.row][END_NODE.col] = E;
// PRINT THE MAZE BEFORE ANY CALCULATIONS
printMaze(maze);
// SOLVE THE MAZE
fillMaze(maze, nodes);
printMaze(maze);
// CONVERT MAZE TO AN ADJACENCY MATRIX
compileMaze(maze);
printMaze(maze);
}
/**
* The parallel arrays define all four directions radiating from
* the dequeued node's location.
*
* Each node will have up to four neighboring cells; some of these
* cells are accessible, some are not.
*
* If a neighboring cell is accessible, we encode it with a directional
* code that calculates the direction we must take should we want to
* navigate to the dequeued node's location from this neighboring cell.
*
* Once encoded into our maze, this neighboring cell is itself queued
* up as a node so that recursively, we can encode the entire maze.
*/
public static final void fillMaze(char[][] maze, List<Node> nodes) {
// dequeue our first node
Node destination = nodes.get(0);
nodes.remove(destination);
// examine all four neighboring cells for this dequeued node
for(int index = 0; index < ROW_DIRECTIONS.length; index++) {
int rowIndex = destination.row + ROW_DIRECTIONS[index];
int colIndex = destination.col + COL_DIRECTIONS[index];
// if this neighboring cell is accessible, encode it and add it
// to the queue
if(maze[rowIndex][colIndex] == O) {
maze[rowIndex][colIndex] = getOppositeDirection(ROW_DIRECTIONS[index], COL_DIRECTIONS[index]);
nodes.add(new Node(rowIndex, colIndex));
}
}
// if our queue is not empty, call this method again recursively
// so we can fill entire maze with directional codes
if(nodes.size() > 0) {
fillMaze(maze, nodes);
}
}
/**
* Converts the maze to an adjacency matrix.
*/
private static void compileMaze(char[][] maze) {
for(int r = 0; r < maze.length; r++) {
for(int c = 0; c < maze[0].length; c++) {
if(maze[r][c] == X || maze[r][c] == O) {
maze[r][c] = FALSE;
}
else {
maze[r][c] = TRUE;
}
}
}
}
/**
* prints the specified two dimensional array
*/
private static final void printMaze(char[][] maze) {
System.out.println("====================================");
for(int r = 0; r < maze.length; r++) {
for(int c = 0; c < maze[0].length; c++) {
System.out.print(maze[r][c] + " ");
}
System.out.print("\n");
}
System.out.println("====================================");
}
/**
* Simply returns the opposite direction from those specified
* by our parallel direction arrays in method fillMaze.
*
* coordinate 1, 1 is the center of the char[][] array and
* applying the specified row and col offsets, we return the
* correct code (opposite direction)
*/
private static final char getOppositeDirection(int row, int col) {
return OPPOSITES[1 + row][1 + col];
}
}
class Node {
int row;
int col;
public Node(int rowIndex, int colIndex) {
row = rowIndex;
col = colIndex;
}
}

create toolbar with my bitmap images

this is an example code of msdn to create toolbar, but this example use the standard images of the system.
What do I need to change in this code to use my images from resource file, for example: IDB_COPY BITMAP "copy.bmp", and IDB_CUT BITMAP "cut.bmp", and IDB_PASTE BITMAP "paste.bmp".
HIMAGELIST g_hImageList = NULL;
HWND CreateSimpleToolbar(HWND hWndParent)
{
// Declare and initialize local constants.
const int ImageListID = 0;
const int numButtons = 3;
const int bitmapSize = 16;
const DWORD buttonStyles = BTNS_AUTOSIZE;
// Create the toolbar.
HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
hWndParent, NULL, g_hInst, NULL);
if (hWndToolbar == NULL)
return NULL;
// Create the image list.
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_COLOR16 | ILC_MASK, // Ensures transparent background.
numButtons, 0);
// Set the image list.
SendMessage(hWndToolbar, TB_SETIMAGELIST,
(WPARAM)ImageListID,
(LPARAM)g_hImageList);
// Load the button images.
SendMessage(hWndToolbar, TB_LOADIMAGES,
(WPARAM)IDB_STD_SMALL_COLOR,
(LPARAM)HINST_COMMCTRL);
// Initialize button info.
// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.
TBBUTTON tbButtons[numButtons] =
{
{ MAKELONG(STD_FILENEW, ImageListID), IDM_NEW, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0, buttonStyles, {0}, 0, (INT_PTR)L"Save"}
};
// Add buttons.
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);
// Resize the toolbar, and then show it.
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar, TRUE);
return hWndToolbar;
}
I found this solution:
const int ID_TB_STANDARD = 0;
const int ID_IL_STANDARD = 0;
HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_TOOLTIPS, 0, 0, 0, 0, hWnd, (HMENU)ID_TB_STANDARD, hInstance, NULL);
HIMAGELIST hImageList = ImageList_LoadBitmap(hInstance, MAKEINTRESOURCEW(IDB_CUT), 16, 0, RGB(255, 0, 255));
ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_COPY)), NULL);
ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PASTE)), NULL);
SendMessage(hWndToolbar, TB_SETIMAGELIST, (WPARAM)ID_IL_STANDARD, (LPARAM)hImageList);
SendMessage(hWndToolbar, (UINT) TB_SETHOTIMAGELIST, 0, (LPARAM)hHotImageList);
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
TBBUTTON tbb[3] =
{
{0,ID_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON},
{1,ID_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON},
{2,ID_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON},
};
SendMessage(hWndToolbar, (UINT) TB_ADDBUTTONS, 3, (LPARAM)&tbb);
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar , SW_SHOW);

Add toolbar Dialogbox with Win32 API

I have a dialog box on which controls are added with resource editor. But I am trying to create a toolbar on the fly in WM_INITGDIALOG message but the toolbar is not visible. Is there something else to do make it visible(I dont think so but...). If this is not possible how can add a toolbar in resource editor.
As you guessed I use VS 2008.
CreateButtons(HWND hwnd)
{
HIMAGELIST m_hTBImageList;
HIMAGELIST m_hTBHottrack;
HWND hwndSysButtonTB = CreateWindowEx(0,
TOOLBARCLASSNAME,
_T(""),
WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NORESIZE | CCS_NOPARENTALIGN,
toolbarRect.left, toolbarRect.top, toolbarRect.right-toolbarRect.left, toolbarRect.bottom-toolbarRect.top,
hwnd,
(HMENU)IDR_TOOLBAR,
(HINSTANCE)hAppInstance,
NULL);
m_hTBImageList = ImageList_LoadImage((HINSTANCE)hAppInstance,
MAKEINTRESOURCE(IDB_BITMAP_ICONS), toolbarButtonSize.cx, 1,
0, IMAGE_BITMAP, LR_CREATEDIBSECTION|LR_SHARED);
m_hTBHottrack = ImageList_LoadImage((HINSTANCE)hAppInstance,
MAKEINTRESOURCE(IDB_MOUSEOVER), toolbarButtonSize.cx, 1,
0, IMAGE_BITMAP, LR_CREATEDIBSECTION|LR_SHARED);
SendMessage(hwndSysButtonTB, (UINT) TB_SETIMAGELIST, 0, (LPARAM)m_hTBImageList);
SendMessage(hwndSysButtonTB, (UINT) TB_SETHOTIMAGELIST, 0, (LPARAM)m_hTBHottrack);
SendMessage(hwndSysButtonTB, (UINT) TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
// win2k: set color of hot tracking frame
COLORSCHEME scheme;
scheme.dwSize = sizeof(scheme);
scheme.clrBtnHighlight = RGB(175,175,175);
scheme.clrBtnShadow = RGB(175,175,175);
SendMessage(hwndSysButtonTB, (UINT) TB_SETCOLORSCHEME, 0, (LPARAM)&scheme);
TBBUTTON ButtonEnd = {0,ID_BUTTON_END,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonRefresh = {1,ID_BUTTON_REFRESH,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonOptions = {2,ID_BUTTON_PROPERTIES,TBSTATE_ENABLED,TBSTYLE_BUTTON};
SendMessage(hwndSysButtonTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonEnd);
SendMessage(hwndSysButtonTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonRefresh);
SendMessage(hwndSysButtonTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonOptions);
}
You have to call
SendMessage(hwndSysButtonTB, TB_AUTOSIZE, 0, 0);
ShowWindow(hwndSysButtonTB , SW_SHOW);
at the end of your function.
And I think you should use an TBBUTTON array instead of three separate variables. Then you can add them all at once with
SendMessage(hwndSysButtonTB, (UINT) TB_ADDBUTTONS, 3, (LPARAM)&ButtonArray);

Resources