Foros del Web » Programación para mayores de 30 ;) » C/C++ »

¿y como se crean los cotroles con la api?

Estas en el tema de ¿y como se crean los cotroles con la api? en el foro de C/C++ en Foros del Web. En el sito conclase, me encontre una tutorl sobre la api, me encanto, esta bastante completa. Algo que me llamo mucho la atencion e como ...
  #1 (permalink)  
Antiguo 25/08/2006, 17:40
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
¿y como se crean los cotroles con la api?

En el sito conclase, me encontre una tutorl sobre la api, me encanto, esta bastante completa.
Algo que me llamo mucho la atencion e como crear los menus desde la api, luego mostro como hacelo mediante el editor.
Sin embargo, despues de paso a los controles pero solo mencio como utilizar el editor.
Quisiera saber que funciones de la api son necesarias y como se utilizan.
__________________
-> La duda adecuada es un buen comienzo <-
  #2 (permalink)  
Antiguo 26/08/2006, 02:04
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
En el tutorial de WinAPI conclase, se crean exjenplos y se explica el manejo de controles creados con un fichero de recursos.

ya que Con el SDK del Win32 se pueden crear controles de 2 formas, con un fichero de recursos y llamando directamente a la funcion CreateWindow ó CreateWindowEx, y en algunos casos muy espesificos, como CreateStatusBarEx se usa la funcion especifica. aunque se puede crear con CreateWindow.

En realidad cuando trabajas con el fichero de recursos, hay un compilador de recursoso, que es el que produce el codigo maguina, que llama a estas funciones.

la forma de crear controles con create windows es muy similar a como se crea la ventana principal.

la diferencia es que El WinAPI ya tienen registradas las clases de los controles comunes con sus respectivos procedimientos de ventana, es por eso que ya no tienes que hacerlo como se hace con la ventana principal o los dialogos.


algunas de las clases son BUTTON, COMBOBOX, EDIT, STATIC, LISTBOX, etc.

pro ejemplo si quieres crear un boton:

//generalmente se crea en el bloque case WM_CREATE: de el procedimiento de ventana.
HWND button1;

case WM_CREATE:
button1 = CreateWindow("BUTTON", "Aceptar",
BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
10,10,80,23,
hwnd, (HMENU)ID_OK, hInstance, NULL);
break;

los parametros de la funcion CreateWindow, los puedes encontrar en el manual, asi como les estilos de ventana y de Button.

con esto ya tienes tu boton, el cual puedes manipular a travez de su hwnd o del ID como cuando se usan recursos.

lo mismo para un TextBox, ListBox, COmbo, etc. solo tienes que especificar la clase de ventana y sus estilos.

Saludos.
  #3 (permalink)  
Antiguo 26/08/2006, 14:39
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
balla ennces si n ventanas los cotroles, lo habia escachado mucho, pero no pensava que se crearian de maneraan homogenea.

gracias Nivel7 esa era teoria buscaba.

dejame hacerte unas peguntas mpro favor.
¿lo menus spueden crear tambien consta metodologia?
¿la barras de aerramentas tamian se puede crear asi?
__________________
-> La duda adecuada es un buen comienzo <-
  #4 (permalink)  
Antiguo 26/08/2006, 20:15
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Las barras de erramientas, son ventanas igual que el resto de los controles asi como la StatusBar, solo que ademas de poder usar CreateWindow para crearla, tambien hay una funcion especifica para eso.

en la cabecera commctrl.h, encontraras las clases registradas de los controles comunes de Windows, asi como alguna otra funcion especifica.

Los menus son ventanas muy particulares, la verdad no estoy muy seguro de que sean ventanas, ya que asta el momento nunca he manejado un menu a travez de su hwnd, no se si lo tengan.

estos no se pueden crear con CreateWindow, sino con CreateMenu(), esto lo explican en una seccion del Manual.

Saludos.

Última edición por Nivel7; 26/08/2006 a las 20:22
  #5 (permalink)  
Antiguo 28/08/2006, 16:34
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
Solo una pregunta mas por favor.

Lo que simepre he qurido hacer es crear ventanas no entandar, como la de wimamp o media player,¿que es lo que me hace falta?
__________________
-> La duda adecuada es un buen comienzo <-
  #6 (permalink)  
Antiguo 29/08/2006, 00:30
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Bueno, en realidad no hay Ventanas no estandar, todas la ventanas que use un programa en Windows, sera un ventana de Windows, no hay otras.

lo que hacen estos programas es usar solo el area cliente de la ventana sin mostrar las demas partes de un formulario clasico.

para esto se usan los estilos de ventana, donde puedes indicar como se mostrara tu ventana.
ejemplo:

WS_CAPTION //para mostrar la barra de titulo.
WS_VISIBLE //para que tu ventana sea visible.
WS_SYSMENU //para que tenga un menu de Sistema
WS_MAXIMIZEBOX //Con boton Maximizar
WS_MINIMIZEBOX //con boton minimizar.
WS_BORODER //con un Borde 3D.

etc.

ademas hay estilos extendidos como:

WS_EX_TOOLBAR //una ventana se muestra como una barra de erramientas flotante.
WS_EX_CLIENTEDGE //una ventana contenedora.

etc.

lo que hacen estos programas es no ponerle caption ni borde y ellos mismos dibujan su propio estilo de ventana.

tambien puedes recortar la region de pintado de la ventana o hacerla invisible.
para hacer ventanas redondeadas o con alguna forma mas compleja.

En fin el tema es super extenso..
para resolver un tema particular tendrias que especificar la seccion de tu programa.

aun que imagino que aun empiezas a conoser el infierno, jeje.

Nunca programe un recorte de ventana con el WinAPI solo con .NET, FoxToolkit y VCL, tal vez lo intente y te muestre el codigo de ejemplo para aclarar mas tu duda.

Saludos.
  #7 (permalink)  
Antiguo 29/08/2006, 02:40
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Ya regrese, aqui tienes un pequeño ejemplo de una ventana modificada en Forma y comportamiento.
No esperes la gran cosa.
no logre comentarlo todo, trata de compilarlo, lo estudias un poco y si quieres despues lo discutimos.


#include <windows.h>


LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
const int IDB_CLOSE = 100;
const int IDB_MAXIMIZE = 101;
const int IDB_MINIMIZE = 102;

//Nombre de la clase de mi ventana.
char szClassName[ ] = "WindowsApp";

//En progra<macion WinAPI se usa WinMain en lugar de main.
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,LPSTR lpszArgument, int nFunsterStil)

{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;


wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = NULL;
wincl.hIconSm = NULL;
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);

//Registro mi clase de ventana para poder crear una venta
//con las caracteristicas que yo quiera usar.

if (!RegisterClassEx (&wincl)) return 0;

//Creao mi ventana indicando el nombre de la clase que registre.
hwnd = CreateWindowEx (
0,
szClassName,
NULL,
WS_SYSMENU|WS_POPUP|WS_VISIBLE, //estos son los estilos de ventana
//en este caso indique que se pueda cerra y que sea visible.
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
300,
NULL,
NULL,
hThisInstance,
NULL
);

ShowWindow (hwnd, nFunsterStil); //Muestor la ventana


//Bucle de mensajes de mi programa
//indispensable en todos los programas con WinAPI.
//a excepcion de los que usan DialogBox como Ventana principal.

while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}

//Solo como regla es importante retornar wParam.
return messages.wParam;
}




LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//declaro las variables locales a mi Procedimiento de ventana
//muchos son estaticos ya que se crearan en una llamada de la funcion y se podran usaran en otra.
static HINSTANCE hInstance;
static RECT rect;
static RECT screen;
static HWND maxButton;
static HWND minButton;
static HWND closButton;
static HRGN rgn;
WINDOWPLACEMENT wp;

//empiesa la captura de mensajes(manejo)
switch (message)
{
case WM_CREATE://Generalmente aqui es donde se crean las ventanas hijas.(controles)
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
closButton = CreateWindow("Button", "Close", BS_PUSHBUTTON|WS_CHILD|WS_DLGFRAME|WS_VISIBLE,
10,10,25,25, hwnd, (HMENU)IDB_CLOSE, hInstance, NULL);
maxButton = CreateWindow("Button", "Max", BS_PUSHBUTTON|WS_CHILD|WS_DLGFRAME|WS_VISIBLE,
35,10,25,25, hwnd, (HMENU)IDB_MAXIMIZE, hInstance, NULL);
minButton = CreateWindow("Button", "Min", BS_PUSHBUTTON|WS_CHILD|WS_DLGFRAME|WS_VISIBLE,
60,10,25,25, hwnd, (HMENU)IDB_MINIMIZE, hInstance, NULL);

//Obtengo el rectangulo del escritorio
GetClientRect(GetDesktopWindow(), &screen);
//Obtengo el rectangulo de mi ventana y la centro en la pantalla.
GetClientRect(hwnd, &rect);
MoveWindow(hwnd, screen.right/2-rect.right/2, screen.bottom/2 - rect.bottom/2, 300, 300, TRUE);
break;
case WM_PAINT:
{
//declaro las variables locales a el evento Paint.
PAINTSTRUCT ps;
HBRUSH hbrush;
HBRUSH hatchb;
HBRUSH blueb;
HPEN hpen;
HPEN redp;
HPEN nullp;
HDC dc;

//Creao mis plumas y brochas que seran seleccionadas para ser usadan en
//el dispositivo de contexto(dc).
hatchb = CreateHatchBrush(HS_CROSS, RGB(0,200,0));
blueb = CreateSolidBrush(RGB(0,0,150));
nullp = (HPEN)GetStockObject(NULL_PEN);
redp = CreatePen(0,5,RGB(255,0,0));
//En WM_PAINT el dc se obtienen con BeginPaint.
dc = BeginPaint(hwnd, &ps);
hbrush = (HBRUSH)SelectObject(dc, blueb);
hpen = (HPEN)SelectObject(dc, nullp);
//Dibujo el rectangulo de pie de ventana.
Rectangle(dc, rect.left, rect.bottom-60, rect.right, rect.bottom);
SelectObject(dc, hatchb);
SelectObject(dc, redp);
//Dibuja un circulo tramado.
Ellipse(dc, 100, 100, rect.right-100, rect.bottom-100);
// Seleciono las plumas y brocha por default.
SelectObject(dc, hbrush);
SelectObject(dc, hpen);
//En WM_PAINT el dc se retorna con EndPaint.
EndPaint(hwnd, &ps);

//Destruyo mis plumas y brochas.
DeleteObject(hatchb);
DeleteObject(blueb);
DeleteObject(nullp);
DeleteObject(redp);

}
break;
case WM_SIZE: //configuro mi ventana y controles.
GetClientRect(hwnd, &rect);
rgn = CreateRoundRectRgn(rect.left+2, rect.top+2, rect.right, rect.bottom,150,150);
SetWindowRgn(hwnd, rgn, TRUE); //Es esta funcion la que hace el recorte.
MoveWindow(closButton, rect.right/2+25, rect.bottom-50, 50,40, TRUE);
MoveWindow(maxButton, rect.right/2-25, rect.bottom-50, 50, 40, TRUE);
MoveWindow(minButton, rect.right/2-75, rect.bottom-50, 50, 40, TRUE);
break;
case WM_COMMAND: //manipulo los mensajes de los botones u otros controles.
switch(LOWORD(wParam))
{
case IDB_CLOSE:
//Destruyo la ventana.(Esto es para mandar el mensaje WM_DESTROY a mi ventana)
DestroyWindow(hwnd);
break;
case IDB_MAXIMIZE:
GetWindowPlacement(hwnd, &wp);
if(wp.showCmd == SW_MAXIMIZE)
ShowWindow(hwnd, SW_RESTORE);
else
ShowWindow(hwnd, SW_MAXIMIZE);
break;
case IDB_MINIMIZE:
ShowWindow(hwnd, SW_MINIMIZE);
break;
}
break;
case WM_DESTROY: // Cierro la aplicacion.
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}

Esta compilado con el DevC++, pero no veo por que no se compile perfectamente en Visual C++ o Builder C++.

Saludos.

Última edición por Nivel7; 29/08/2006 a las 02:47
  #8 (permalink)  
Antiguo 31/08/2006, 16:42
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
claro.....
hoy mismo lo boy a compilar....


gracias.
__________________
-> La duda adecuada es un buen comienzo <-
  #9 (permalink)  
Antiguo 01/09/2006, 17:39
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
uhhhh... que simple es el cocepto de ventana, veraz pesaba que era algo asi como un conjunto de funciones y variables en dll.
Es que aun no entiendo como es que Wndows reconoces los destinatarios de los mesajes.
__________________
-> La duda adecuada es un buen comienzo <-
  #10 (permalink)  
Antiguo 01/09/2006, 18:07
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
ahhh... para eso es el area cliente?

La ventana activa es la que esta detro del area cliente, y windows solo hace esta revicion?.
asi de simple?.
__________________
-> La duda adecuada es un buen comienzo <-
  #11 (permalink)  
Antiguo 01/09/2006, 21:04
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
No, no lo creo.

Una cosa es el manejo de mensajes y otra lo relacionado con el area cliente, y si, en realidad programar con el API es super complejo, y todo se encuentra en funciones de las DLLs. jeje
C++ a diferencia de otros lenguajes incluye ya un SDK listo para usarse con loas funciones del API, es por eso que no eres tu quien lo tienen que hacer como en VB u tros lenguajes.

pero si tu quisieras podrias hacerlo, por ejemplo, si quieres agregar funciones del SDK de Windows Vista pues lo tendrias que hacer tu mismo.

por ejemplo:

extern "C" __declspec(dllimport) LONG CreateVistaDialog(HWND, HINSTANCE, LPSTR, INT);

//la funcion en realidad no existe es solo un ejemplo;

ya con esta definicion ya la puedes usar.

si quieres puedes revisar los encabezados, por ejemplo winuser.h
ahi veras como se invocan las funciones del API.

las ventanas de windows tienen un manipulador Handle, que no es un puntero a una estructura, sino un entero producto de un Hash(Supongo) con la verdadera direccion de la estructura que describe a una ventana.

es atraves de este manipulador que window se comunica con las ventanas y entre ellas.

la estructura MSG, es la encargada de recoger los mensajes de la cola de Mensajes de Windows,

se hace con GetMessage(&msg, 0, 0, 0);
esta funcion se encarga de almacenar en la estructura MSG el manipulador, las coordenadas del raton entre otros datos, para que el Procedimiento de ventana puede hacer su trabajo.

el Procedimiento de ventana es invokado a traves del puntero en la estructura WNDCLASSEX, por la Funcion:
DispatchMessage(&msg);

imagino que lo primero que hace es obtener el puntero al Procedimiento de ventana a travez del manipulador contenido en MSG.
por ejemplo;

void DispatchMessage(MSG *msg)
{
WNDPROC procedure = (WNDPROC)GetWindowLong(msg->hwnd, GWL_WNDPROC);
CallWindowProc(procedure, hwnd, msg, msg.wParam, msg.lParam);
}

es tan solo un ejemplo de lo que realmente hace esta funcion.

TranslateMessage(), tan solo se encarga de convertir el codigo de formato del teclado en codigo ASCII o UNICODE segun sea.

la forma de seleccionar el manipulador correcto puede hacerlo de 2 formas a traves de la pocision del rato, o por la posicion del Foco.

ahora, la ventana no solo esta conformada por el area cliente, tambien cuenta con un area llamada Area no Cliente.
El Area Cliente es aqulla que sera otorgada por el sistema patra que tu puedas crear tu aplicacion(Dibujar).
y el area no cliente generalmente solo el SO, puede acceder a elLa(Aun que puedes acceder con un poco mas de trabajo), para dibujar el estilo de ventana, los controles de Max,Min,Close, Help, ect.

Como podras ver un boton o cualquier otro control es una ventana, sin caption, ni borde, su procedimiento de ventana de BUTTON, por ejemplo es el que se encarga de Dibujar en el area cliente de la ventana BUTTON, la forma de un PUSHBUTTON, y su comportamiento respectivo.

hay otros controles que estan conformados por dos o mas ventanas, por ejemplo el ComboBox.


En fin como podras ver es un tema super extenso, poco a poco iras aprendiendo sobre el WINAPI.

Saludos.

Última edición por Nivel7; 01/09/2006 a las 21:16
  #12 (permalink)  
Antiguo 02/09/2006, 14:19
arm
 
Fecha de Ingreso: mayo-2006
Mensajes: 112
Antigüedad: 18 años, 7 meses
Puntos: 0
exelente!!!!!!!!!!!!!!!!!!!!!!!!!

gracias........
__________________
-> La duda adecuada es un buen comienzo <-
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:56.