I am making an message box in python 2.7 on windows 7 64 bit machine. It will rise to show error message to user in message box.
import ctypes
msgbox = ctypes.windll.user32.MessageBoxA
ret = msgbox(None, 'message', 'title', 0)
print ret
This shows the required message box. But in taskbar the default image of python appears which is annoying. So, how to include image in taskbar. Or just not to show default image of python in taskbar.
This is because you don't have a window, None
, and then the system will assign a default icon.
You can install a hook using SetWindowsHookEx
and then alter MessageBox
icon. For example let's use StackOverflow icon.
#-*- coding: utf-8 -*-
#!python
from ctypes import *
from ctypes.wintypes import *
#recommended
#from ctypes import windll, c_int, c_int64, c_long, WINFUNCTYPE, POINTER, cast, c_wchar, byref
#from ctypes.wintypes import HMODULE, LPCWSTR, HANDLE, HINSTANCE, UINT, HWND, WPARAM, LPARAM, HHOOK, DWORD, BOOL, RECT, POINT
from os import path
import platform
#################################################################
RelPath = lambda file : path.join(path.dirname(path.abspath(__file__)), file)
#################################################################
GetModuleHandle = windll.kernel32.GetModuleHandleW
GetModuleHandle.restype = HMODULE
GetModuleHandle.argtypes = [LPCWSTR]
#################################################################
IMAGE_ICON = 1
LR_LOADFROMFILE = 0x00000010
LR_CREATEDIBSECTION = 0x00002000
LoadImage = windll.user32.LoadImageW
LoadImage.restype = HANDLE
LoadImage.argtypes = [HINSTANCE, LPCWSTR, UINT, c_int, c_int, UINT]
#################################################################
LRESULT = c_int64 if platform.architecture()[0] == "64bit" else c_long
SendMessage = windll.user32.SendMessageW
SendMessage.restype = LRESULT
SendMessage.argtypes = [HWND, UINT, WPARAM, LPARAM]
#################################################################
MB_OK = 0x00000000L
MessageBox = windll.user32.MessageBoxW
MessageBox.restype = c_int
MessageBox.argtypes = [HWND, LPCWSTR, LPCWSTR, UINT]
#################################################################
WH_CBT = 5
HCBT_ACTIVATE = 5
HOOKPROC = WINFUNCTYPE(LRESULT, c_int, WPARAM, LPARAM)
SetWindowsHookEx = windll.user32.SetWindowsHookExW
SetWindowsHookEx.restype = HHOOK
SetWindowsHookEx.argtypes = [c_int, HOOKPROC, HINSTANCE, DWORD]
#################################################################
CallNextHookEx = windll.user32.CallNextHookEx
CallNextHookEx.restype = LRESULT
CallNextHookEx.argtypes = [HHOOK, c_int, WPARAM, LPARAM]
#################################################################
GetCurrentThreadId = windll.kernel32.GetCurrentThreadId
GetCurrentThreadId.restype = DWORD
GetCurrentThreadId.argtypes = None
#################################################################
UnhookWindowsHookEx = windll.user32.UnhookWindowsHookEx
UnhookWindowsHookEx.restype = BOOL
UnhookWindowsHookEx.argtypes = [HHOOK]
#################################################################
# code starts here
def MyMessageBox(hWnd, lpText, lpCaption, uType, lpIcon):
hHook = HHOOK(None)
#**********************************************************#
# center button code
def EnumChildProc(hwnd, lParam):
ClassName = (c_wchar * 7)()
if GetClassName(hwnd, ClassName, 7) > 0:
if ClassName.value.lower() == "button":
wrect = RECT()
GetClientRect(lParam, byref(wrect))
brect = RECT()
GetClientRect(hwnd, byref(brect))
bpoint = RECT()
MapWindowPoints(hwnd, lParam, cast(byref(bpoint), POINTER(POINT)), 2)
MoveWindow(hwnd,
((wrect.right - wrect.left) - (brect.right - brect.left)) // 2,
bpoint.top,
brect.right - brect.left,
brect.bottom - brect.top,
True)
return False
return True
WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, LPARAM)
EnumChildWindows = windll.user32.EnumChildWindows
EnumChildWindows.restype = BOOL
EnumChildWindows.argtypes = [HWND, WNDENUMPROC, LPARAM]
GetClassName = windll.user32.GetClassNameW
GetClassName.restype = HWND
GetClassName.argtypes = [HWND, LPCWSTR, c_int]
GetClientRect = windll.user32.GetClientRect
GetClientRect.restype = BOOL
GetClientRect.argtypes = [HWND, POINTER(RECT)]
MoveWindow = windll.user32.MoveWindow
MoveWindow.restype = BOOL
MoveWindow.argtypes = [HWND, c_int, c_int, c_int, c_int, BOOL]
MapWindowPoints = windll.user32.MapWindowPoints
MapWindowPoints.restype = c_int
MapWindowPoints.argtypes = [HWND, HWND, POINTER(POINT), UINT]
#**********************************************************#
def AlterIcon(_hWnd, lpszIcon):
WM_SETICON = 0x0080
ICON_BIG = 1
hModel = GetModuleHandle(None)
hIcon = LoadImage(hModel,
RelPath(lpszIcon),
IMAGE_ICON,
0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION)
SendMessage(_hWnd, WM_SETICON, ICON_BIG, hIcon)
def CBTProc(nCode, wParam, lParam):
if nCode == HCBT_ACTIVATE:
_hWnd = cast(wParam, HWND)
AlterIcon(_hWnd, lpIcon)
#**********************************************************#
pEnumChildProc = WNDENUMPROC(EnumChildProc)
EnumChildWindows(_hWnd, pEnumChildProc, _hWnd.value)
#**********************************************************#
CallNextHookEx(hHook, nCode, wParam, lParam)
return 0
# WARNING: don't pass HOOKPROC(CBTProc) directly to SetWindowsHookEx
pCBTProc = HOOKPROC(CBTProc)
hHook = SetWindowsHookEx(WH_CBT, pCBTProc, None, GetCurrentThreadId())
MessageBox(hWnd, lpText, lpCaption, uType)
UnhookWindowsHookEx(hHook)
# example of usage
MyMessageBox(None, "Hello world!", "Title", MB_OK, "favicon.ico")
Most the code is just functions prototype. Now you can call MyMessageBox
as:
MyMessageBox(None, "Hello world!", "Title", MB_OK, "favicon.ico")
result:
UPDATE: it will center the button now by enumerating through the message box window's chillers and looking for a button, then center it. I haven't test it much but it looks OK so far.