Aprenderemos qué son los contrioles comunes y cómo usarlos. Este tutorial sólo será una introducción rápida a ellos.
Bajar el ejemplo de código fuente aquí.
Windows 95
viene con varias ampliaciones de la interface de usuario sobre Windows 3.1x.
Esas ampliaciones enriquecen la GUI. Algunas de ellas eran apliamente usadas
antes de que Windows 95 llegara a los almacenes, tales como la barra de estado
[status bar], barras de herramientas etc. Los programadores tenían que
escribir el código para estas ampliaciones. Ahora Microsoft las ha incluido
con Windows 9x y NT. Aprenderemos sobre ellas aquí.
Estos son los nuevos controles:
Ya que hay muchos, cargarlos todos en memoria y registrarlos sería un despilfarro de recursos. Todos ellos, con excepción del control "rich edit", están almacenados en comctl32.dll, desde donde las aplicaciones pueden cargarlas cuando se quiera usarlos. El control "rich edit" reside en su propia dll, richedXX.dll, porque es muy complicado y debido a que es más grande que su brethren.
Puedes cargar comctl32.dll incluyendo una llamada a InitCommonControls en tu programa.
InitCommonControls
es una función en comctl32.dll, así que refiriéndola en
cualquier parte del código de tu programa hará que el cargador
de archivos PE cargue comctl32.dll cuando corra tu programa.No tienes que
ejecutarla , sólo inclúyela en algún lugar de tu código.
¡Esta función no hace NADA! Su unica instrucción
es "ret". Su único propósito es incluir la referencia a comctl32.dll
en la sección de importación de manera que el caragador de archivos
PE lla cargue cada vez que el programa sea caragado. El verdaero canalllo de
batalla es el punto de entrada de la fucnión en la DLL que registra todas
las clases de controles comunes cuando es cargada la dll. Los controles comunes
son creados sobre la base de esas clases así como los controles de ventana
hija tales como "edit", "listbox", etc.
El control
"rich edit" es otra cosa. Si quieres usarlo, tienes que llamar a a
LoadLibrary para caragarlo explícitamente y luego llamar a FreeLibrary
para descargarlo.
Ahora aprenderemos cómo crearlos. Puedes usar un editor de recursos para incorporarlos en las cajas de diálogo o puedes crearlos túmismo. Casi todos los controles comunes se crean llamando a CreateWindowEx o a CreateWindow, pasando le el nombre de la clse del control. Algunos controles comunes tienen funciones de creación específicas, sin embargo, they are just wrappers around CreateWindowEx para facilitar la creación de esos controles. Las funciones de creación específicas existenetes son:
|
|
ToolbarWindow32 | Toolbar |
tooltips_class32 | Tooltip |
msctls_statusbar32 | Status bar |
SysTreeView32 | Tree view |
SysListView32 | List view |
SysAnimate32 | Animación |
SysHeader32 | Header |
msctls_hotkey32 | Hot-key |
msctls_progress32 | Progress bar |
RICHEDIT | Rich edit |
msctls_updown32 | Up-down |
SysTabControl32 | Tab |
Los controles property sheets, property pages y image list tienen sus propias funciones de creación específicas. Los controles drag list son cajas de listas [listbox] potenciadas así que no tienen su propia clase. Los nombres de las clases de arriba pueden ser verificados chequeando el guión de recursos generado por el editor de recursos de Visual C++. Difieren de los nombres de clase que aparecen en la lista de la referencia de la api de Windows de Borland y de la lista del libro Programación en Windows 95 de Charles Petzold. La lista de arriba es la precisa.
Esos controles comunes pueden usar estilos de ventana generales tales como WS_CHILD, etc. También tienen sus estilos específicos tales como TVS_XXXXX para el control tree view, LVS_xxxx para el control list view, etc. La referencia de la api de Win32 es tu mejor amigo en este punto.
Ahora que sabemos cómo crear controles comunes, podemos ver el método de comunicación entre los controles comunes y sus padres. A diferencia de los controles de ventanas hija, los controles comunes no se comunican con el padre a través de WM_COMMAND. En vez de eso, ellos envían mensajes WM_NOTIFY a la ventana padre cuando algunos eventos interesantes ocurren con ellos. El padre puede controlar al hijo enviándoles mensajes. También hay muchos mensajes para los nuevos controles. Deberías consultar tu referencia de la api de win32 para más detalles.
Vamos ver los controles de barra de progreso [progress bar] y barra de estado [status bar] en el siguiente ejemplo.
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
.const
IDC_PROGRESS
equ 1 ; IDs
de los controles
IDC_STATUS
equ 2
IDC_TIMER
equ 3
.data
ClassName
db "CommonControlWinClass",0
AppName
db "Common Control Demo",0
ProgressClass
db "msctls_progress32",0 ; el nombre de
la clase de la barra de progreso
Message
db "Finished!",0
TimerID
dd 0
.data?
hInstance
HINSTANCE ?
hwndProgress
dd ?
hwndStatus
dd ?
CurrentStep
dd ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax
invoke InitCommonControls
WinMain
proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_APPWORKSPACE
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain
endp
WndProc
proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_CREATE
invoke CreateWindowEx,NULL,ADDR ProgressClass,NULL,\
WS_CHILD+WS_VISIBLE,100,\
200,300,20,hWnd,IDC_PROGRESS,\
hInstance,NULL
mov hwndProgress,eax
mov eax,1000
; the lParam of PBM_SETRANGE message contains the range
mov CurrentStep,eax
shl eax,16
; the high range is in the high word
invoke SendMessage,hwndProgress,PBM_SETRANGE,0,eax
invoke SendMessage,hwndProgress,PBM_SETSTEP,10,0
invoke CreateStatusWindow,WS_CHILD+WS_VISIBLE,NULL,hWnd,IDC_STATUS
mov hwndStatus,eax
invoke SetTimer,hWnd,IDC_TIMER,100,NULL
; crear un temporizador
mov TimerID,eax
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.if TimerID!=0
invoke KillTimer,hWnd,TimerID
.endif
.elseif uMsg==WM_TIMER
;
cuando ocurre un evento de temporizador
invoke SendMessage,hwndProgress,PBM_STEPIT,0,0 ; incrementar
el progreso en la barra de progreso
sub CurrentStep,10
.if CurrentStep==0
invoke KillTimer,hWnd,TimerID
mov TimerID,0
invoke SendMessage,hwndStatus,SB_SETTEXT,0,addr Message
invoke MessageBox,hWnd,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION
invoke SendMessage,hwndStatus,SB_SETTEXT,0,0
invoke SendMessage,hwndProgress,PBM_SETPOS,0,0
.endif
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc
endp
end start
Si esta llamada tiene éxito, regresará el TimerID. Si falla, regresa 0. Esto se debe a que el valor del ID del temporizador debe ser diferente a cero.
[Iczelion's Win32 Assembly Homepage]
n u M I T_o r's Programming Page
Este tutorial, original de Iczelion, ha sido traducido por: n u M I T_o r